【发布时间】:2016-02-25 15:53:47
【问题描述】:
我正在尝试使用 C# 中的以下算法对 XML 文档进行签名:
当我尝试使用随机 RSA 密钥对其进行签名时,它可以完美运行。
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = false;
xmlDoc.Load("hpbtest.xml");
RSA Key = new RSACryptoServiceProvider(2048);
// Create a SignedXml object.
PrefixedSignedXML signedXml = new PrefixedSignedXML(xmlDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "#xpointer(//*[@authenticate='true'])";
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
// Add an enveloped transformation to the reference.
XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();
env.Algorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Compute the signature.
signedXml.ComputeSignature("ds");
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml("ds");
// Append the element to the XML document.
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
xmlDoc.Save("hpbtest.xml");
但如果我想使用 OpenSSL 生成的证书中的 RSA 密钥:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = false;
xmlDoc.Load("hpbtest.xml");
RSA Key = new GestionCertificat("CN=Bruno").getClePrivee();//Get the private key
// Create a SignedXml object.
PrefixedSignedXML signedXml = new PrefixedSignedXML(xmlDoc);
// Add the key to the SignedXml document.
signedXml.SigningKey = Key;
signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
// Create a reference to be signed.
Reference reference = new Reference();
reference.Uri = "#xpointer(//*[@authenticate='true'])";
reference.DigestMethod = "http://www.w3.org/2001/04/xmlenc#sha256";
// Add an enveloped transformation to the reference.
XmlDsigExcC14NTransform env = new XmlDsigExcC14NTransform();
env.Algorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
reference.AddTransform(env);
// Add the reference to the SignedXml object.
signedXml.AddReference(reference);
// Compute the signature.
signedXml.ComputeSignature("ds");
// Get the XML representation of the signature and save
// it to an XmlElement object.
XmlElement xmlDigitalSignature = signedXml.GetXml("ds");
// Append the element to the XML document.
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
xmlDoc.Save("hpbtest.xml");
我得到这个错误:
指定的算法无效
在这两个示例中,我的 RSA 密钥具有相同的长度 (2048),我不知道为什么会出现此错误。
谢谢!
托马斯
【问题讨论】:
-
什么是
PrefixedSignedXML?您是否可能使用第三方 CMS 提供商或硬件设备? -
PrefixedSignedXML是 SignedXML 的类继承,用于在签名元素上添加“ds”前缀。我使用 Makecert 生成我的证书。我也尝试使用 OpenSSL 生成证书,但我遇到了同样的问题。