我在数字签名XML消息时遇到问题。要求规定ECDSA证书将与特定曲线一起使用。这意味着由该SignedXml.ComputeSignature(...)
方法提供的RSA和DSA功能将没有创造的SignatureDescription
,AsymmetricSignatureFormatter
和AsymmetricSignatureDeformatter
定制的实施工作。密钥不存在 - 使用自签名ECDSA证书
这就是说,并没有过多的代码我已经创建了一个简单的函数,应该拿一个证书,并使用其公钥签名数据使用ECDsaCng
类,因为这是我用来创建上述自定义实现。
会发生什么情况是,即使我的自定义实现,我得到抛出“System.Security.Cryptography.CryptographicException: Key does not exist.
”异常。但是,如果我只是创建CngKey
而不是导入它,它的工作原理。从我所看到的这个异常被抛出被调用方法上internal static extern ErrorCode NCryptSignHash(...)
的代码是在ncrypt.dll
的所以我的问题是,为什么会抛出异常“System.Security.Cryptography.CryptographicException: Key does not exist.
”以及如何解决它。
[TestMethod]
public void CreateSignatureTest()
{
var request = "Some xml goes here...";
var store = new X509Store(StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadOnly);
var certificates = store.Certificates;
var applicableCertificate = certificates.Cast<X509Certificate2>()
.FirstOrDefault(certificate => certificate.Subject.Contains("ECDSA_CERT_NAME"));
var encryptingKey = (ECDsaCng)applicableCertificate.GetECDsaPublicKey();
var exported = encryptingKey.Key.Export(CngKeyBlobFormat.EccPublicBlob);
var creationParameters = new CngKeyCreationParameters
{
ExportPolicy = CngExportPolicies.AllowPlaintextExport
};
using (CngKey objCngKey = CngKey.Import(exported, CngKeyBlobFormat.EccPublicBlob)) // This will throw a Key Does Not Exist Exception
//using (CngKey objCngKey = CngKey.Create(CngAlgorithm.ECDsaP256, null, creationParameters)) // This works...
{
//'Convert String to be signed to a byte array
var data = Encoding.Default.GetBytes(request);
//'Create a ECDsaCng Object
var ecdsa = new ECDsaCng(objCngKey);
//'Sign the string
var bSignature = ecdsa.SignData(data);
//'Convert Signature to Base64 string for better reading
var sSignature = Convert.ToBase64String(bSignature);
}
}
我试过这个 var encryptingKey =(ECDsaCng)applicableCertificate.GetECDsaPrivateKey(); VAR导出=((ECDsaCng)encryptingKey).Key.Export(CngKeyBlobFormat.EccPrivateBlob);现在得到一个不同的异常“请求的操作不被支持。”我的印象是,我会加密与公众和接收器将验证对私钥? – Geek
这就是加密的工作原理,是的;但签署是相反的。签名者使用私钥(只有他们拥有),验证者使用公共。但我仍然不明白你为什么要克隆这个对象(这对于一张智能卡来说不起作用)。 'cert.GetECDsaPrivateKey()。SignData(...)'(虽然using语句都不错) – bartonjs
的最后注释是一个很好的指针,我拿出克隆,现在我可以签回一个签名。我现在剩下的唯一问题是如何将它应用于自定义的SignatureDescription,AsymmetricSignatureFormatter和AsymmetricSignatureDeformatter实现,然后创建Signature XML节点。 – Geek