我正在尝试将使用Win32 Crypto API生成的RSA公钥/私钥对导入到.NET应用程序中。创建和导出密钥对的代码如下所示:
// Abbreviated for clarity.
CryptAcquireContext(..., MS_ENHANCED_PROV, ...);
// Generate public/private key pair
CryptCreateHash(..., CALG_SHA1, ...);
CryptHashData(hash, password, ...);
CryptDeriveKey(..., CALG_3DES, hash, CRYPT_EXPORTABLE, ...);
CyrptExportKey(..., derivedKey, PRIVATEKEYBLOB, ...);
基本上,此代码将公钥/私钥对导出为加密的blob。它使用3DES算法进行加密,密钥来自sha-1散列。
现在,当我尝试将此密钥导入.NET时,会遇到问题。我试图接近:
(1)我创建一个rsacyRptoServiceProvider对象并调用importCSPBlob()。这会引发一个异常消息“坏数据”。这并不奇怪,因为提供程序对象无法知道blob是如何加密的。据我所知,根本没有办法告诉它使用什么算法和密钥。
(2)我使用passwordDeriveBytes类手动解密blob,然后将解密的blob传递给importcsbblob()。再一次,我得到一个例外。这一次,消息是“提供程序的错误版本”。我在创建提供程序对象时尝试手动提供提供提供程序名称(“Microsoft Enhanced Cryptographic Provider v1.0”),但没有任何区别。
我要把这个工作做好是很重要的。有什么想法吗?
解决方案
在C++和.NET中生成未加密的公钥/私钥对之后,我发现微软增强密码提供者实际上不加密密钥对的前8字节。(这必须是为循环抛出.NET包装的版本控制信息。)在修改了.NET解密代码以使前8个字节保持不变之后,一切都正常工作。
这个解决方案不是很好,因为它依赖于加密提供程序的内部实现细节。不幸的是,我认为没有其他方法,因为微软忽略了提供importcspblob的版本,该版本允许您指定用于解密的算法和密钥。