使用PKCS11 interop签名Xml

时间:2018-01-02 07:51:19

标签: c# xml xml-dsig pkcs11interop

我想使用pkcs11Interop库签署XML,我使用下面的代码签署XML但签名验证失败。

当我使用System.Security.Cryptography.Xml.SignedXml签名时,会通过签名验证。

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

遵循的步骤

  1. 生成XmlDsigC14NTransform并创建sha1哈希。
  2. 使用pkcs11interop签名哈希。
  3. 代码

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

0 个答案:

没有答案