2017-10-13 100 views
1

我有以下代碼:有關在.net framework 4.7中執行ECDiffieHellmanCng的祕密協議的問題?

 var curve = ECCurve.NamedCurves.nistP256; 
     var ecdhSender = ECDiffieHellman.Create(curve); 
     var ecdhReceiver = ECDiffieHellman.Create(curve); 

我的理解是,我應該能夠計算祕密協議,無論是從使用ecdhSender對象使用ecdhReceiver.PublicKey或使用與ecdhSender.PublicKey ecdhReceiver對象和兩個祕密協議值應相同。如果這是一個錯誤的假設,請讓我知道。

由於ECDiffieHellman.Create返回ECDiffieHellman類型,我寫了下面的代碼來獲取祕密協議:

 string receiverHexString = null; 
     using (SafeNCryptSecretHandle secretAgreement = (ecdhReceiver as ECDiffieHellmanCng).DeriveSecretAgreementHandle(ecdhSender.PublicKey)) 
     { 
      byte[] secretAgreementBytes = new byte[32]; 
      IntPtr pointer = secretAgreement.DangerousGetHandle(); 
      Marshal.Copy(pointer, secretAgreementBytes, 0, secretAgreementBytes.Length); 
      receiverHexString = BitConverter.ToString(secretAgreementBytes).Replace("-", string.Empty).ToLower(); 
      Console.WriteLine($"receiver secretAgreement: 0x{receiverHexString}"); 
     } 

     string senderHexString = null; 
     using (SafeNCryptSecretHandle secretAgreement = (ecdhSender as ECDiffieHellmanCng).DeriveSecretAgreementHandle(ecdhReceiver.PublicKey)) 
     { 
      byte[] secretAgreementBytes = new byte[32]; 
      IntPtr pointer = secretAgreement.DangerousGetHandle(); 
      Marshal.Copy(pointer, secretAgreementBytes, 0, secretAgreementBytes.Length); 
      senderHexString = BitConverter.ToString(secretAgreementBytes).Replace("-", string.Empty).ToLower(); 
      Console.WriteLine($"sender secretAgreement: 0x{senderHexString}"); 
     } 

     Assert.AreEqual(receiverHexString, senderHexString); 

我斷言失敗。顯然我做錯了一些事情(如果祕密協議應該是相同的)。

難道我是如何提取字節的句柄嗎?或者是其他東西?

+0

你想完成什麼? NCRYPT_SECRET_HANDLE結構是不透明的,你不應該讀它的內存。 – bartonjs

+0

嘗試使用詳細步驟驗證來自合作伙伴的結果。如果在我的問題的第一部分中,我的假設是正確的還是錯誤的,請您評論一下嗎? – Raghu

回答

1

last time I checked開始,沒有文檔記載的方式從CNG獲取原始祕密協議值,這就是.NET不公開它的原因。

在.NET的預期使用ECDH的是

ECCurve curve = ECCurve.NamedCurves.nistP256; 

// Usually you'll only have one private key (yours), so this isn't representative of 
// real code. An `ECDiffieHellman` object doesn't necessarily have a private key, 
// but an `ECDiffieHellmanPublicKey` object definitely doesn't. 
using (ECDiffieHellman bobPrivate = ECDiffieHellman.Create(curve)) 
using (ECDiffieHellman alicePrivate = ECDiffieHellman.Create(curve)) 
using (ECDiffieHellmanPublicKey bobPublic = bobPrivate.PublicKey) 
using (ECDiffieHellmanPublicKey alicePublic = alicePrivate.PublicKey) 
{ 
    byte[] ba = bobPrivate.DeriveKeyFromHash(alicePublic, HashAlgorithmName.SHA256); 
    byte[] ab = alicePrivate.DeriveKeyFromHash(bobPublic, HashAlgorithmName.SHA256); 

    // ba and ab have the same contents. 
} 

還有

  • DeriveKeyFromHash(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] secretPrepend, byte[] secretAppend)
  • DeriveKeyFromHmac(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] hmacKey)
  • DeriveKeyFromHmac(ECDiffieHellmanPublicKey otherPartyPublicKey, HashAlgorithmName hashAlgorithm, byte[] hmacKey, byte[] secretPrepend, byte[] secretAppend)
  • DeriveKeyTls(ECDiffieHellmanPublicKey otherPartyPublicKey, byte[] prfLabel, byte[] prfSeed)

如果bobPrivate和alicePublic(或者相反,alicePrivate和bobPublic)不變,那麼提供相同的輸入將產生相同的輸出。

注意:你應該避免專門討論ECDiffieHellmanCng,如果可以的話。當ECDH最終將其轉換爲.NET標準時,ECDHCng類不會。從.NET 4.6.2開始,一切都可以在基類上完成(打開持久鍵除外);而.NET Core往往不會從其工廠方法中返回公共類型。