如何将RSA私钥导入RSACryptoServiceProvider?

时间:2010-11-17 19:01:25

标签: .net interop cryptography

我正在尝试将使用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中生成未加密的公钥/私钥对后,我发现Microsoft Enhanced Cryptographic Provider实际上并不加密密钥对的前8个字节。 (这必须是为循环抛出.NET包装器的版本信息。)在修改我的.NET解密代码以保留前8个字节后,一切正常。

此解决方案不是很好,因为它取决于加密提供程序的内部实现detials。不幸的是,我认为没有任何其他办法,因为微软忽略了提供一个版本的ImportCspBlob,它允许你指定一个算法和解密密钥。

1 个答案:

答案 0 :(得分:2)

在方法2)中,验证解密密钥与加密前相同。

我不认为“从SHA-1哈希派生的密钥”将与PasswordDeriveBytes中的密钥匹配