2016-12-05 49 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,這些角色通常稱爲服務器(私鑰持有者)和客戶端(另一方)。