我在对 XML 消息进行数字签名时遇到问题。要求规定 ECDSA 证书将与特定曲线一起使用。这意味着该SignedXml.ComputeSignature(...)
方法提供的 RSA 和 DSA 功能如果不创建SignatureDescription
,AsymmetricSignatureFormatter
和AsymmetricSignatureDeformatter
.
话虽如此,并且没有发布大量代码,我创建了一个简单的函数,该函数应该获取证书并使用其公钥使用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);
}
}