代码之家  ›  专栏  ›  技术社区  ›  Peter Ruderman

如何将RSA私钥导入RSACryptoServiceProvider?

  •  2
  • Peter Ruderman  · 技术社区  · 14 年前

    我正在尝试将使用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的版本,该版本允许您指定用于解密的算法和密钥。

    1 回复  |  直到 14 年前
        1
  •  2
  •   Henk Holterman    14 年前

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

    我不认为“从sha-1哈希派生的密钥”会与从passwordDeriveBytes派生的密钥匹配