如何在 .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 方法,这应该已经适合您了。
假设 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 方法,这应该已经适合您了。