I am using version "xml-crypto": "^4.0.1"
node version v16.14.0
Error displayed as
invalid signature: for uri calculated digest is 2U1suBt1sOA2olbnbMK1gC/3FHk= but the xml to validate supplies digest OGXcEIgUP1W+Hv9ghexl8gdMtrI=
Generated XML
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol">
<saml:Assertion MajorVersion="1" MinorVersion="1"
AssertionID="_1" Issuer="mydomain.com"
IssueInstant="2023-08-13T03:01:27.265Z" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion"
Id="_0">
<saml:Conditions NotBefore="2023-08-13T03:01:27.266Z"
NotOnOrAfter="2023-08-14T03:01:27.263Z" />
<saml:AuthenticationStatement AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:password"
AuthenticationInstant="2023-08-13T03:01:27.268Z">
<saml:Subject>
<saml:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
NameQualifier="urn:mydomain.com">123356</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
</saml:AuthenticationStatement>
<saml:AttributeStatement>
<saml:Subject>
<saml:NameIdentifier Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
NameQualifier="urn:mydomain.com">123356</saml:NameIdentifier>
<saml:SubjectConfirmation>
<saml:ConfirmationMethod>urn:oasis:names:tc:SAML:1.0:cm:bearer</saml:ConfirmationMethod>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Attribute AttributeName="version" AttributeNamespace="mydomain.com">
<saml:AttributeValue>1</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
<samlp:Status>
<samlp:StatusCode Value="samlp:Success" />
</samlp:Status>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>OGXcEIgUP1W+Hv9ghexl8gdMtrI=</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>
HKJ/iE4XpJlwQW9H0zP8yK6SZO/HazYl/YpE09GTwDFcsgPRots+nosEeVtVU0wLkYW6wNgwf79LEoTiEComatyuRhVWg3ZtZpsdSkrkfR74M2B9aECoPS8k5tqArQbJl0KO...[redacted]...tsRlIJX9nMtdg==</SignatureValue>
</Signature>
</samlp:Response>
I used the following function to strip the spaces from the XML
function removeXMLSpaces(string){
let xmlString = string;
xmlString = xmlString.replace(/>\s*/g, ">");
xmlString = xmlString.replace(/\s*</g, "<");
xmlString = xmlString.replace(/\r\n?/g, "\n");
xmlString = xmlString.replace(/(\r\n\t|\n|\r\t)/gm, "");
return xmlString;
}
Here is my SignXML function used
function signXml(xml, options) {
console.log({ options });
const sig = new SignedXml(options);
// sig.keyInfoProvider = new KeyProvider();
sig.signatureAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1";
sig.canonicalizationAlgorithm = "http://www.w3.org/TR/2001/REC-xml-c14n-20010315";
sig.addReference({
xpath: "//*[local-name(.)='Assertion']",
transforms: ["http://www.w3.org/2000/09/xmldsig#enveloped-signature"]
});
sig.computeSignature(xml);
fs.writeFileSync(process.cwd() + "/xml/signed.xml", sig.getSignedXml());
let currentSignedXML = sig.getSignedXml();
currentSignedXML = currentSignedXML.replace("Id=\"_0\"","").replace("URI=\"#_0\"","URI=\"\"");
return currentSignedXML;
}
So...i found the issue. I am not sure if this requires an update to validation.
For it to work, I had to add the transform for C14n. On reading the documentation, I believe that this was a default value but on inspecting the code in the package, I saw the value was missing in the validationXML which caused the mismatch.
Also note that I changes the xpath to "Response" and took @srd90 suggestion for appending the signature.
See github issue: https://github.com/node-saml/xml-crypto/issues/376