如何将 RSA 私钥导入到 RSACryptoServiceProvider 中?

发布于 2024-10-02 14:53:05 字数 1136 浏览 1 评论 0原文

我正在尝试将使用 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 增强型加密提供程序 v1.0”),但这没有什么区别。

让这个工作正常进行是至关重要的。有什么想法吗?

解决方案

在 C++ 和 .NET 中生成未加密的公钥/私钥对后,我发现 Microsoft 增强型加密提供程序实际上并未加密密钥对的前 8 个字节。 (这肯定是导致 .NET 包装器陷入循环的版本控制信息。)修改我的 .NET 解密代码以保留前 8 个字节后,一切正常。

该解决方案不是很好,因为它取决于加密提供程序的内部实现细节。不幸的是,我认为没有其他方法,因为 Microsoft 忽略了提供一个可以让您指定解密算法和密钥的 ImportCspBlob 版本。

I'm trying to import an RSA public/private key pair generated with the Win32 Crypto API into a .NET application. The code that creates and exports the key pair looks something like this:

// 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, ...);

Basically, this code is exporting the public/private key pair as an encrypted blob. It uses the 3DES algorithm for the encryption with a key derived from a SHA-1 hash.

Now, when I try to import this key into .NET, I get problems. I've tried to approaches:

(1) I create an RSACyrptoServiceProvider object and call ImportCspBlob(). This throws an exception with the message "bad data." That's not surprising since the provider object has no way to know how the blob was encrypted. As far as I can tell, there's no way at all to tell it what algorithm and key to use for this.

(2) I manually decrypt the blob myself, using the PasswordDeriveBytes class, and then pass the decrypted blob to ImportCsbBlob(). Once again, I get an exception. This time the message is "bad version of provider." I tried manually supplying the provider name ("Microsoft Enhanced Cryptographic Provider v1.0") when creating the provider object, but it makes no difference.

It's critical that I get this working. Any ideas?

SOLUTION

After generating the unencrypted public/private key pairs in both C++ and .NET, I discovered that the Microsoft Enhanced Cryptographic Provider does not actually encrypt the first 8-bytes of the key pair. (This must be the versioning information that was throwing the .NET wrapper for a loop.) After modifying my .NET decryption code to leave the first 8 bytes alone, everything works fine.

This solution isn't very good since it depends on internal implementation detials of the cryptographic provider. Unfortunately, I don't think there's any other way since Microsoft neglected to provide a version of ImportCspBlob that lets you specify an algorithm and key for decryption.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

陈甜 2024-10-09 14:53:05

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

我认为“从 SHA-1 哈希派生的密钥”不会与来自 PasswordDeriveBytes 的密钥相匹配

In approach 2), verify the decrypted key is the same as before encryption.

I don't think "a key derived from a SHA-1 hash" will match one from PasswordDeriveBytes

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文