gpt4 book ai didi

c# - SignedXml 使用 SHA256 计算签名

转载 作者:IT王子 更新时间:2023-10-29 04:52:25 24 4
gpt4 key购买 nike

我正在尝试使用 SHA256 对 XML 文档进行数字签名。

我正在尝试使用 Security.Cryptography.dll为此。

这是我的代码-

CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription),"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

X509Certificate2 cert = new X509Certificate2(@"location of pks file", "password");
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(@"input.xml");

SignedXml signedXml = new SignedXml(doc);
signedXml.SigningKey = cert.PrivateKey;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

//
// Add a signing reference, the uri is empty and so the whole document
// is signed.
Reference reference = new Reference();
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
reference.Uri = "";
signedXml.AddReference(reference);

//
// Add the certificate as key info, because of this the certificate
// with the public key will be added in the signature part.
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
// Generate the signature.
signedXml.ComputeSignature();

但我收到“指定的算法无效”。 signedXml.ComputeSignature(); 处出错。谁能告诉我我做错了什么?

最佳答案

X509Certificate2 将私钥从 pfx 文件加载到 Microsoft Enhanced Cryptographic Provider v1.0(提供程序类型 1 又名 PROV_RSA_FULL) 不支持 SHA-256。

基于 CNG 的加密提供程序(在 Vista 和 Server 2008 中引入)比基于 CryptoAPI 的提供程序支持更多的算法,但是 .NET 代码似乎仍然可以使用基于 CryptoAPI 的类,例如 RSACryptoServiceProvider 而不是 RSACng,所以我们必须解决这些限制。

但是,另一个 CryptoAPI 提供程序 Microsoft Enhanced RSA and AES Cryptographic Provider(提供程序类型 24 a.k.a. PROV_RSA_AES)确实支持 SHA-256。因此,如果我们将私钥输入该提供程序,我们就可以使用它进行签名。

首先,您必须调整您的 X509Certificate2 构造函数,使 key 能够从 X509Certificate2 通过添加 X509KeyStorageFlags.Exportable 标志:

X509Certificate2 cert = new X509Certificate2(
@"location of pks file", "password",
X509KeyStorageFlags.Exportable);

并导出私钥:

var exportedKeyMaterial = cert.PrivateKey.ToXmlString(
/* includePrivateParameters = */ true);

然后为支持 SHA-256 的提供商创建一个新的 RSACryptoServiceProvider 实例:

var key = new RSACryptoServiceProvider(
new CspParameters(24 /* PROV_RSA_AES */));
key.PersistKeyInCsp = false;

并将私钥导入其中:

key.FromXmlString(exportedKeyMaterial);

创建SignedXml 实例后,告诉它使用key 而不是cert.PrivateKey:

signedXml.SigningKey = key;

它现在可以工作了。

这是 list of provider types and their codes在 MSDN 上。

这是您的示例的完整调整代码:

CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

X509Certificate2 cert = new X509Certificate2(@"location of pks file", "password", X509KeyStorageFlags.Exportable);

// Export private key from cert.PrivateKey and import into a PROV_RSA_AES provider:
var exportedKeyMaterial = cert.PrivateKey.ToXmlString( /* includePrivateParameters = */ true);
var key = new RSACryptoServiceProvider(new CspParameters(24 /* PROV_RSA_AES */));
key.PersistKeyInCsp = false;
key.FromXmlString(exportedKeyMaterial);

XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load(@"input.xml");

SignedXml signedXml = new SignedXml(doc);
signedXml.SigningKey = key;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

//
// Add a signing reference, the uri is empty and so the whole document
// is signed.
Reference reference = new Reference();
reference.AddTransform(new XmlDsigEnvelopedSignatureTransform());
reference.AddTransform(new XmlDsigExcC14NTransform());
reference.Uri = "";
signedXml.AddReference(reference);

//
// Add the certificate as key info, because of this the certificate
// with the public key will be added in the signature part.
KeyInfo keyInfo = new KeyInfo();
keyInfo.AddClause(new KeyInfoX509Data(cert));
signedXml.KeyInfo = keyInfo;
// Generate the signature.
signedXml.ComputeSignature();

关于c# - SignedXml 使用 SHA256 计算签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29005876/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com