在.net framework 4.7中实现ECDiffieHellmancing时有关保密协议的问题?

在.net framework 4.7中实现ECDiffieHellmancing时有关保密协议的问题?,.net,cryptography,elliptic-curve,.net,Cryptography,Elliptic Curve,我有以下代码: var curve = ECCurve.NamedCurves.nistP256; var ecdhSender = ECDiffieHellman.Create(curve); var ecdhReceiver = ECDiffieHellman.Create(curve); 我的理解是,我应该能够使用ecdhSender对象和ecdhReceiver.PublicKey计算秘密协议,或者使用ecdhReceiver对象和ecd

我有以下代码:

        var curve = ECCurve.NamedCurves.nistP256;
        var ecdhSender = ECDiffieHellman.Create(curve);
        var ecdhReceiver = ECDiffieHellman.Create(curve);
我的理解是,我应该能够使用ecdhSender对象和ecdhReceiver.PublicKey计算秘密协议,或者使用ecdhReceiver对象和ecdhSender.PublicKey计算秘密协议,并且两个秘密协议值应该相同。如果这是一个错误的假设,请让我知道

由于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);
我的主张失败了。显然我做错了什么(如果秘密协议应该是一样的)

这就是我将字节从句柄中提取出来的方式吗?还是别的什么?

到目前为止,还并没有从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其他部分publickey,byte[]prfLabel,byte[]prfSeed)
如果bobPrivate和alicePublic(或者相反,alicePrivate和bobPublic)保持不变,则提供相同的输入将产生相同的输出


注意:如果可以的话,你应该避免特别谈论
ecdiffiehellmancing
。当ECDH最终成为.NET标准时,ECDHCng类就不会了。从.NET 4.6.2开始,所有操作都可以在基类上完成(除了打开持久化键);NET内核倾向于不从其
Create()
工厂方法返回公共类型。

您想实现什么?NCRYPT_SECRET_句柄结构不透明,您不应该读取它的内存。请尝试使用详细步骤验证合作伙伴的结果。在问题的第一部分,你能评论一下我的假设是正确的还是错误的吗?