2017-10-13 9 views
1

Je code suivant:Questions sur l'accord secret de l'implémentation ECDiffieHellmanCng dans .net framework 4.7?

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

Ma compréhension est que je devrais pouvoir calculer accord secret, soit d'utiliser l'objet ecdhSender à l'aide ecdhReceiver.PublicKey ou en utilisant l'objet ecdhReceiver avec ecdhSender.PublicKey et que les deux valeurs de l'accord secrète ne être le même. Si c'est une mauvaise hypothèse, s'il vous plaît faites le moi savoir.

Depuis le ECDiffieHellman.Create retourne le type ECDiffieHellman, j'écrit le code ci-dessous pour obtenir l'accord secret:

 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); 

Mon affirmation est défaillante. Évidemment, je fais quelque chose de mal (si les accords secrets sont censés être les mêmes).

Est-ce que c'est comme ça que j'extrais les octets de la poignée? Ou autre chose?

+0

Qu'essayez-vous d'accomplir? La structure NCRYPT_SECRET_HANDLE est opaque, vous ne devriez pas lire sa mémoire. – bartonjs

+0

Essayer de valider les résultats d'un partenaire avec des étapes détaillées. Pouvez-vous s'il vous plaît commenter si mon hypothèse est correcte ou fausse dans la première partie de ma question? – Raghu

Répondre

1

À partir du last time I checked, il n'existe aucun moyen documenté d'obtenir la valeur de l'accord secret brut du GNC, ce qui explique pourquoi .NET ne l'expose pas.

L'utilisation prévue de ECDH dans .NET est

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

Il y a aussi

  • 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)

Si bobPrivate et alicePublic (ou, inversement, alicePrivate et bobPublic) sont inchangés, fournir les mêmes entrées produira les mêmes sorties.

Remarque: Vous devriez éviter de parler spécifiquement de ECDiffieHellmanCng, si vous le pouvez. Lorsque ECDH finit par entrer dans .NET Standard, la classe ECDHCng ne le fera pas. À partir de .NET 4.6.2 tout peut être fait sur la classe de base (excepté l'ouverture des clés persistantes); et .NET Core a tendance à ne pas renvoyer les types publics de ses méthodes-usine Create().