2016-12-05 53 views
0

我试图使用名为KeyExchange的公用类将.NET RSAPKCS1KeyExchangeFormatter类的示例从https://msdn.microsoft.com/EN-US/library/8kkwbeez(v=VS.110,d=hv.2).aspx拆分为2个控制台应用程序(Alice,Bob)。该类包含两种方法: GenerateEncryptedSessionKeyAndIV:在Alice上运行,加密会话密钥,并用于测试目的对其进行解密。 ProcessEncryptedSessionKeyAndIV:在Bob上运行,未能用Exception“The parameter is incorrect”解密会话密钥。尽管字节数组看起来是正确的。请帮忙。.NET RSAPKCS1KeyExchangeFormatter类 - 异常“参数不正确”

 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. 
    } 
+0

堆栈跟踪会很有用。 – bartonjs

回答

0

好的,心理调试时间。

  • 您有Alice构建其中之一并致电GenerateEncryptedSessionKeyAndIV()。她发送该值,并且值为PublicKey(不应该是属性,因为每次按F10时,它都会比调试器中发生的工作多得多)。
  • 您有Bob构建其中一个并分配PublicKey,然后致电ProcessEncryptedSessionKeyAndIV

唯一的例外是因为鲍勃没有私钥,所以他无法解密。

你正在做KeyExchange,这表明你在线,这表明你应该只使用TLS并在一天内调用它。如果您处于离线状态,您需要KeyAgreement(Diffie-Hellman,或EC Diffie-Hellman)。

然而,正确的做法是

  • 私有密钥持有者将自己的公钥,最好作为证书
  • 对方验证的公共密钥(这是当它是一个证书容易得多.. 。在不可能的近了,如果只是关键数据)
  • 对方产生一些数据隐藏
  • 对方使用加密接收到的公钥
  • 对方发送ENCR数据返回数据返回
  • 私钥持有者解密数据(使用私钥)
  • 现在双方都知道数据是什么(这可能是一个关键,可能是一个关键+算法,可能是一个输入KDF,...)

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