有关 .net Framework 4.7 中 ECDiffieHellmanCng 实现的秘密协议的问题吗?

2024-03-24

我有以下代码:

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

我的理解是,我应该能够通过使用 ecdhReceiver.PublicKey 使用 ecdhSender 对象或使用 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);

我的主张失败了。显然我做错了一些事情(如果秘密协议应该是相同的)。

这是我从句柄中提取字节的方式吗?或者是其他东西?


截至上次我检查过 https://stackoverflow.com/a/46440614/6535399没有记录的方法可以从 CNG 获取原始秘密协议值,这就是 .NET 不公开它的原因。

ECDH 在 .NET 中的预期用途是

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)未更改,则提供相同的输入将产生相同的输出。

Note:你应该避免谈论ECDiffieHellmanCng具体来说,如果可以的话。当 ECDH 最终进入 .NET 标准时,ECDHCng 类不会。从 .NET 4.6.2 开始,一切都可以在基类上完成(除了打开持久化的键);并且 .NET Core 往往不会从其返回公共类型Create()工厂方法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有关 .net Framework 4.7 中 ECDiffieHellmanCng 实现的秘密协议的问题吗? 的相关文章

随机推荐