繁体   English   中英

Firma SOAP 错误 Hash 值不匹配 [关闭]

[英]Firma SOAP error Hash values do not match [closed]

         <faultcode>env:Server</faultcode>
         <faultstring>0x00d30003: Hash values do not match.</faultstring>
         <detail>
            <errorCode>0x00d30003</errorCode>
            <errorMessage>Hash values do not match.</errorMessage>
            <RqUID/>
         </detail>
public static void firmarxmlconcertificado(XmlDocument xmlSalida, X509Certificate2 cert)
        {
            const string STR_SOAPENV = "http://schemas.xmlsoap.org/soap/envelope/";
            const string STR_WSSE = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
            const string STR_WSU = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd";
            const string STR_DS = "http://www.w3.org/2000/09/xmldsig#";
            const string STR_EC = "http://www.w3.org/2001/10/xml-exc-c14n#";

            var ns = new XmlNamespaceManager(xmlSalida.NameTable);
            ns.AddNamespace("soapenv", STR_SOAPENV);
            ns.AddNamespace("wsse", STR_WSSE);
            ns.AddNamespace("wsu", STR_WSU);
            ns.AddNamespace("ds", STR_DS);
            ns.AddNamespace("ec", STR_EC);

            var idKeyInfo = "KI-" + Guid.NewGuid().ToString("N").ToUpper();
            var idWsu = "STR-" + Guid.NewGuid().ToString("N").ToUpper();
            var idwsseRef = "X509-" + Guid.NewGuid().ToString("N").ToUpper();
            var IdUriRef = "id-" + Guid.NewGuid().ToString("N").ToUpper() + Guid.NewGuid().ToString("N").Substring(0, 2).ToUpper();
            var IdSecTok = "SIG-" + Guid.NewGuid().ToString("N").ToUpper();

            const String RSA = "1.2.840.113549.1.1.1";
            const String DSA = "1.2.840.10040.4.1";
            const String ECC = "1.2.840.10045.2.1";


            //SignedXml PrivateKey

            SignedXml signedXml = new SignedXml(xmlSalida);
            RSA rsa = cert.GetRSAPrivateKey();
            signedXml.SigningKey = rsa;
            signedXml.SigningKeyName = cert.SubjectName.Name;
            signedXml.Signature.Id = IdSecTok;

            //Soap Body
            XmlElement soapbody = xmlSalida.DocumentElement.SelectSingleNode(@"//soapenv:Body", ns) as XmlElement;
            soapbody.SetAttribute("wsu:Id", IdUriRef);
            soapbody.SetAttribute("xmlns:wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");

            //Reference
            Reference reference = new Reference();
            reference.DigestMethod = SignedXml.XmlDsigSHA256Url;
            reference.Uri = "";           
            XmlDsigExcC14NTransform transform = new XmlDsigExcC14NTransform();
            reference.AddTransform(transform);
            transform.InclusiveNamespacesPrefixList = "ifx v1 v2";

            //SignedXml
            signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA256Url;
            signedXml.SignedInfo.CanonicalizationMethod = SignedXml.XmlDsigExcC14NTransformUrl;
            XmlDsigExcC14NTransform canMethod = (XmlDsigExcC14NTransform)signedXml.SignedInfo.CanonicalizationMethodObject;
            canMethod.InclusiveNamespacesPrefixList = "ifx soapenv v1 v2";
            signedXml.AddReference(reference);

            //KeyInfo
            KeyInfo keyInfo = new KeyInfo();
            keyInfo.Id = idKeyInfo;            
            KeyInfoNode keyInfoNode = new KeyInfoNode();
            XmlElement wsseSec = xmlSalida.CreateElement("wsse","SecurityTokenReference", string.Empty);
            XmlElement wsseRef = xmlSalida.CreateElement("wsse", "Reference", string.Empty);
            wsseSec.SetAttribute("wsu:Id", idWsu);
            wsseRef.SetAttribute("URI","#" + idwsseRef);
            wsseRef.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
            wsseSec.AppendChild(wsseRef);
            keyInfoNode.Value = wsseSec;
            keyInfo.AddClause(keyInfoNode);
            signedXml.KeyInfo = keyInfo;
            signedXml.ComputeSignature();            
            XmlElement xmlsig = signedXml.GetXml();

            //Header 
            //Wsse:security
            XmlElement soapSignature = xmlSalida.DocumentElement.SelectSingleNode(@"//wsse:Security", ns) as XmlElement;
            XmlAttribute sId = xmlSalida.CreateAttribute("Id");
            sId.Value = IdSecTok;
            xmlsig.Attributes.Append(sId);
            // *** And add our signature as content            
            soapSignature.AppendChild(xmlsig);

            //wsse:BinarySecurityToken
            XmlElement soapBinSecTok = xmlSalida.DocumentElement.SelectSingleNode(@"//wsse:BinarySecurityToken", ns) as XmlElement;
            soapBinSecTok.SetAttribute("EncodingType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary");
            soapBinSecTok.SetAttribute("ValueType", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3");
            soapBinSecTok.SetAttribute("wsu:Id", idwsseRef);
            var export = cert.Export(X509ContentType.Cert);
            var base64 = Convert.ToBase64String(export);
            soapBinSecTok.InnerText = base64;

            XmlElement referenceUri = xmlSalida.DocumentElement.SelectSingleNode(@"//ds:Reference", ns) as XmlElement;
            referenceUri.SetAttribute("URI", "#" + IdUriRef);

            //Prefix
            SetPrefix("ds", xmlsig);            
            signedXml.LoadXml(xmlsig);            
            signedXml.SignedInfo.References.Clear();            
            signedXml.ComputeSignature();
            string recomputedSignature = Convert.ToBase64String(signedXml.SignatureValue);
            // Replace value of the signature with recomputed one
            ReplaceSignature(xmlsig, recomputedSignature);

            //doc.DocumentElement.AppendChild(doc.ImportNode(xmlsig, true));
        }

        private static void SetPrefix(string prefix, XmlNode node)
        {
            node.Prefix = prefix;
            foreach (XmlNode n in node.ChildNodes)
            {

                SetPrefix(prefix, n);
            }

            if (node.NamespaceURI == "http://www.w3.org/2001/10/xml-exc-c14n#")
                node.Prefix = "ec";
            else if ((node.NamespaceURI == "http://www.w3.org/2000/09/xmldsig#") || (string.IsNullOrEmpty(node.Prefix)))
                node.Prefix = prefix;

        }
        //xmlDSignSecurityUrl

        private static void ReplaceSignature(XmlElement signature, string newValue)
        {
            if (signature == null) throw new ArgumentNullException(nameof(signature));
            if (signature.OwnerDocument == null) throw new ArgumentException("No owner document", nameof(signature));

            XmlNamespaceManager nsm = new XmlNamespaceManager(signature.OwnerDocument.NameTable);
            nsm.AddNamespace("ds", SignedXml.XmlDsigNamespaceUrl);

            XmlNode signatureValue = signature.SelectSingleNode("ds:SignatureValue", nsm);

            if (signatureValue == null)
                throw new Exception("Signature does not contain 'ds:SignatureValue'");

            signatureValue.InnerXml = newValue;
        }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM