1

我想使用 pkcs11Interop 库对 XML 进行签名,我正在使用以下代码对 XML 进行签名,但签名验证失败。

当我System.Security.Cryptography.Xml.SignedXml用来签名时,它通过了签名验证。

我的方法生成的 DigestValue 和 SignedXml 相同,但签名不同,即使我使用相同的证书进行签名。

遵循的步骤

  1. 生成 XmlDsigC14NTransform 并创建 sha1 哈希。
  2. 使用 pkcs11interop 对哈希进行签名。

代码

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;
        }
    }
4

0 回答 0