I am receiving a SAML 2.0 AuthnRequest:
<saml2p:AuthnRequest xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol" Version="2.0">
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:CanonicalizationMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference xmlns:ds="http://www.w3.org/2000/09/xmldsig#" URI="#_ab854a268099a9abfedf74deb5148576">
<ds:Transforms xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:Transform xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod xmlns:ds="http://www.w3.org/2000/09/xmldsig#" Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">YPAxelno504BpWNYxlaBfI5y8gQDhczpCKvN9poGLco=</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
mcyNOzAqR8ir6dLLqujXhMKWlat3zJpaIumR8+KNoiDjHaa5pfKGXbTQHg7fazyezX4IHFygFV+/
jrUfZNZJrPsGvpN02yTiJceFnaBmlWF9z1RRIZ4hJfh6wJU/9lzCWhfRf4qaChvt0ex8qgLJX7UF
Uu6yGEo96kROu6EA7PttmZhWKyPqSc3k7IuzLFDzaxykTbYRZfogvySD97okbG38Hl4huGyJMe2m
oHQqShZrEtLJl7WlmIgam6dJ5VwxHIBxHVAq5iHNnxISqJ3vYvTMbKVMJ7Ek8UlK7Sxox0cQBonn
RcvsgGdYIrfqUz4+3dulZartsDOeBJTI35OYAQ==
</ds:SignatureValue>
</ds:Signature>
</saml2p:AuthnRequest>
My understanding is that the signature embedded in this AuthnRequest is generated using the application's private key. I do not have access to the private key, but I have the public key.
I want to verify that this AuthnRequest was signed with the correct private key, by using the matching public key that I have available. I tried the following:
const certificate = `-----BEGIN CERTIFICATE-----
......
-----END CERTIFICATE-----`;
const signature = 'mcyNOzAqR8ir6dLLqujXhMKWlat3zJpaIumR8+KNoiDjHaa5pfK.....'; // from the xml
const publicKeyBuffer = Buffer.from(certificate, 'utf-8');
const signatureBuffer = Buffer.from(signature, 'utf-8');
const verifier = crypto.createVerify('RSA-SHA256');
verifier.update(samlMessage);
const valid = verifier.verify(publicKeyBuffer, signatureBuffer);
As value for samlMessage, I tried using both the base64 encoded and deflated query parameter as well as the decoded XML above.
Unfortunately this tells me that the signature is invalid either way, even though I know it is correct. What am I doing wrong?