[英]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.