我想使用pkcs11Interop库签署XML,我使用下面的代码签署XML但签名验证失败。
当我使用System.Security.Cryptography.Xml.SignedXml
签名时,会通过签名验证。
我的方法和SignedXml生成的DigestValue是相同的,但签名是不同的,即使我使用相同的证书进行签名。
遵循的步骤
代码
public static string SignXml(string xmlValueToSign)
{
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlValueToSign);
XmlDsigC14NTransform xmlDsigC14NTransform = new XmlDsigC14NTransform();
xmlDsigC14NTransform.LoadInput(xmlDoc);
using (Stream xmlDsigC14NTransformStream = (Stream)xmlDsigC14NTransform.GetOutput(typeof(Stream)))
{
SHA1 sha1 = SHA1.Create();
byte[] hash = sha1.ComputeHash(xmlDsigC14NTransformStream);
string base64DigestString = Convert.ToBase64String(hash);
string xmlSignatureValue = "";
//Get session
//get private key handle
using (Mechanism mechanism = new Mechanism(CKM.CKM_RSA_PKCS))
xmlSignatureValue = Session.Sign(mechanism, PrivateKeyHandle, hash);
string base64CertificateValue = Convert.ToBase64String(x509Certificate2.RawData);
string nameSpace = "http://www.w3.org/2000/09/xmldsig#";
XmlDocument signatureDoc = new XmlDocument();
XmlElement signatureElement = signatureDoc.CreateElement(string.Empty, "Signature", nameSpace);
signatureDoc.AppendChild(signatureElement);
//SignedInfo
XmlElement signedInfoElement = signatureDoc.CreateElement(string.Empty, "SignedInfo", nameSpace);
signatureElement.AppendChild(signedInfoElement);
//CanonicalizationMethod
XmlElement canonicalizationMethodElement = signatureDoc.CreateElement(string.Empty, "CanonicalizationMethod", nameSpace);
canonicalizationMethodElement.SetAttribute("Algorithm", "http://www.w3.org/TR/2001/REC-xml-c14n-20010315");
signedInfoElement.AppendChild(canonicalizationMethodElement);
//SignatureMethod
XmlElement signatureMethodElement = signatureDoc.CreateElement(string.Empty, "SignatureMethod", nameSpace);
signatureMethodElement.SetAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#rsa-sha1");
signedInfoElement.AppendChild(signatureMethodElement);
//Reference
XmlElement referenceElement = signatureDoc.CreateElement(string.Empty, "Reference", nameSpace);
referenceElement.SetAttribute("URI", "");
signedInfoElement.AppendChild(referenceElement);
//Transforms
XmlElement transformsElement = signatureDoc.CreateElement(string.Empty, "Transforms", nameSpace);
referenceElement.AppendChild(transformsElement);
//Transform
XmlElement transformElement = signatureDoc.CreateElement(string.Empty, "Transform", nameSpace);
transformElement.SetAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#enveloped-signature");
transformsElement.AppendChild(transformElement);
//DigestMethod
XmlElement digestMethodElement = signatureDoc.CreateElement(string.Empty, "DigestMethod", nameSpace);
digestMethodElement.SetAttribute("Algorithm", "http://www.w3.org/2000/09/xmldsig#sha1");
referenceElement.AppendChild(digestMethodElement);
//DigestValue
XmlElement digestValueElement = signatureDoc.CreateElement(string.Empty, "DigestValue", nameSpace);
XmlText digestValue = signatureDoc.CreateTextNode(base64DigestString);
digestValueElement.AppendChild(digestValue);
referenceElement.AppendChild(digestValueElement);
//SignatureValue
XmlElement signatureValueElement = signatureDoc.CreateElement(string.Empty, "SignatureValue", nameSpace);
XmlText signatureValue = signatureDoc.CreateTextNode(xmlSignatureValue);
signatureValueElement.AppendChild(signatureValue);
signatureElement.AppendChild(signatureValueElement);
//KeyInfo
XmlElement keyInfoElement = signatureDoc.CreateElement(string.Empty, "KeyInfo", nameSpace);
signatureElement.AppendChild(keyInfoElement);
//X509Data
XmlElement x509DataElement = signatureDoc.CreateElement(string.Empty, "X509Data", nameSpace);
keyInfoElement.AppendChild(x509DataElement);
//X509Certificate
XmlElement x509CertificateElement = signatureDoc.CreateElement(string.Empty, "X509Certificate", nameSpace);
XmlText x509CertificateValue = signatureDoc.CreateTextNode(base64CertificateValue);
x509CertificateElement.AppendChild(x509CertificateValue);
x509DataElement.AppendChild(x509CertificateElement);
xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(signatureElement, true));
var signedXml = xmlDoc.OuterXml;
return signedXml;
}
}
catch (Exception)
{
throw;
}
}