.NET RSAPKCS1KeyExchangeFormatter类 - 异常"参数不正确"

时间:2016-12-05 21:37:23

标签: c# encryption

我尝试使用名为KeyExchange的公共类将.NET https://msdn.microsoft.com/EN-US/library/8kkwbeez(v=VS.110,d=hv.2).aspx中的.NET RSAPKCS1KeyExchangeFormatter类的示例拆分为2个控制台应用程序(Alice,Bob)。该类包含两个方法: GenerateEncryptedSessionKeyAndIV:在Alice上运行,加密会话密钥,并出于测试目的对其进行解密。 ProcessEncryptedSessionKeyAndIV:在Bob上运行,无法使用Exception解密会话密钥"参数不正确"。虽然字节数组看起来正确。请帮忙。

       public KeyExchange()
    {
        rsaKey = new RSACryptoServiceProvider();    // asymmetric encryption/decryption
        aes = new AesCryptoServiceProvider();       // symmetric encryption/decryption
    }

    public byte[] PublicKey
    {
        get { return rsaKey.ExportCspBlob(false); }   // used by partner who wants to send secret session key
        set { rsaKey.ImportCspBlob(value); }          // used by partner who receives secret session key
    }

    public void GenerateEncryptedSessionKeyAndIV(out byte[] iv, out byte[] encryptedSessionKey)
    {
        iv = aes.IV; // Gets the initialization vector (IV) for the symmetric algorithm.

        // Encrypt the session key
        RSAPKCS1KeyExchangeFormatter keyFormatter = new RSAPKCS1KeyExchangeFormatter(rsaKey);  // Initializes a new instance of the RSAPKCS1KeyExchangeFormatter class with the specified key.
        encryptedSessionKey = keyFormatter.CreateKeyExchange(aes.Key, typeof(Aes));         // Create and return the encrypted key exchange data

        // test only: the next 2 lines are to prove that the secret key can be obtained from the the encrypted key exchange data here on Alice,
        // the same code failes executed on Bob (see method ProcessEncryptedSessionKeyAndIV)
        RSAPKCS1KeyExchangeDeformatter keyDeformatter = new RSAPKCS1KeyExchangeDeformatter(rsaKey);
        byte[] helper = keyDeformatter.DecryptKeyExchange(encryptedSessionKey);
    }

    public void ProcessEncryptedSessionKeyAndIV(byte[] iv, byte[] encryptedSessionKey)
    {
         aes.IV = iv; // Sets the initialization vector (IV) for the symmetric algorithm.

        // Decrypt the session key, Create a KeyExchangeDeformatter
        RSAPKCS1KeyExchangeDeformatter keyDeformatter = new RSAPKCS1KeyExchangeDeformatter(rsaKey);
        // obtain the secret key (32 bytes) from from the encrypted key exchange data (128 bytes)
        aes.Key = keyDeformatter.DecryptKeyExchange(encryptedSessionKey);  // this results in CryptographicException: The parameter is incorrect. 
    }

1 个答案:

答案 0 :(得分:0)

好的,精神调试时间。

  • 你让Alice构建其中一个并调用GenerateEncryptedSessionKeyAndIV()。她发送了这个值,以及PublicKey的值(它不应该是属性,因为每次点击F10时,它比调试器中发生的工作要多得多)。
  • 您让Bob构建其中一个并分配PublicKey,然后致电ProcessEncryptedSessionKeyAndIV

例外是因为Bob没有私钥,所以他无法解密。

您正在进行KeyExchange,这表明您已在线,这表明您应该只使用TLS并将其称为一天。如果您处于离线状态,则需要KeyAgreement(Diffie-Hellman或EC Diffie-Hellman)。

然而,正确的方法是

  • 私钥持有者发送他们的公钥,最好是证书
  • 其他方验证公钥(当它是证书时更容易......如果它只是关键数据,那就不可能了)
  • 其他方生成一些数据以隐藏
  • 其他方使用收到的公钥加密数据
  • 其他方发回加密数据
  • 私钥持有者解密数据(使用私钥)
  • 现在双方都知道数据是什么(可能是关键,可能是关键+算法,也可能是KDF的输入,......)

对于KeyExchange,这些角色通常称为服务器(私钥持有者)和客户端(其他方)。

相关问题