如何在 .net Framework 4.7.1 中使用 ECDSA 和 ECDiffieHellman 实例对消息进行签名?

How to sign a message using ECDSA with an ECDiffieHellman instance in .net framework 4.7.1?

假设 ECDiffieHellman 实例也可用于签名。

如果我有有效的 ECDiffieHellman (ECDH) 实例,如何在 .net 框架中使用 ECDSA 实例创建签名?

我想我可以通过以下方式验证签名:

        ECDiffieHellman ecdh;   //Already have this instance
        var verifyKey = CngKey.Import(ecdh.PublicKey.ToByteArray(), CngKeyBlobFormat.EccPublicBlob);
        var ecDsa = new ECDsaCng(verifyKey);
        var dataBytes = ASCIIEncoding.ASCII.GetBytes("Hello!");
        var verifyResult = ecDsa.VerifyData(dataBytes, signatureBytesToCheck, HashAlgorithmName.SHA256);

我尝试遵循 CngKey 的类似模型作为私钥(用于签名)。我在使用私钥字节创建 CngKey 时遇到问题。

        ECDiffieHellman ecdh;   //Already have this instance
        var ecdhParams = ecdhCasd.ExportParameters(true);
        var ecdhPrivateKeyBytes = ecdhParams.D;
        var signingKey = CngKey.Import(ecdhPrivateKeyBytes, CngKeyBlobFormat.EccPrivateBlob);

我尝试使用 GenericPrivateBlob、EccFullPrivateBlob 进行格式化。仍然没有任何效果。

我走的路对吗?如果是这样,我做错了什么?

我比我想象的要近得多。我终于想到我只需要使用 Create 方法而不是 Import 方法,如下所示:

    ECDiffieHellman ecdh;   //Already have this instance
    var ecdhParams = ecdhCasd.ExportParameters(true);
    var signer = ECDsa.Create(ecFullParams);
    var signedBytes = ecDsa.SignData(dataBytes, HashAlgorithmName.SHA256);

如果我只有 public 个密钥来验证:

    ECDiffieHellmanPublicKey ecdhPk; //Compute this with public key bytes
    var ecPkParams = ecdhPk.ExportParameters();
    var verifier = ECDsa.Create(ecPkParams);
    var verifyResult = verifier.VerifyData(bytesToBeVerified, signatureBytesToCheck, HashAlgorithmName.SHA256);

除了导出密钥属性之外,您应该能够使用不可导出的密钥来执行此操作:

ECDiffieHellmanCng ecdhChg = ecdh as ECDiffieHellmanCng;

// Export is required.
if (ecdhCng == null)
    return null;

return new ECDsa(ecdhCng.Key);

这是因为在 Windows CNG "ECDSA" 密钥上只允许做 ECDSA;但是 "ECDH" 密钥可以同时执行 ECDSA 和 ECDH。至少,软件私钥是这样。

.NET 开始允许在 .NET 4.6.2 中通过 ECDH 密钥创建 ECDsaCng,因此如果您有可用的 ECC ExportParameters 方法,这应该已经适合您了。