Please help, if anyone knows why the "Hash values do not match" error occurs, I am sending a self-signed XML, but when consuming the service it presents the error indicated below.
<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>
This is the code with which I am creating the XML file, from .net, in which the document with the header is already fully created, as requested by the service to consume.
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;
}