SAML Signature verification failed

Vid L picture Vid L · Oct 19, 2013 · Viewed 26k times · Source

Our IdP is a Salesforce.com org. The SP is a third party .Net application. During development, the 3rd party reported that they're unable to validate the SAML response sent.

We decided to try validating on our end using ComponentSpace to validate the SAML response. Below is what we tried:

// Load the certificate from the file: certInFile
// Load the SAML in an XMLElement: samlXml
// Retrieve the certificate from the SAML: certInSaml

Console.WriteLine("SAML is valid ? " + SAMLResponse.IsValid(samlXml));
Console.WriteLine("Is SAML signed? " + SAMLMessageSignature.IsSigned(samlXml));
Console.WriteLine("Certificate found in SAML is same as certificate file? " + certInFile.Equals(certInSaml));
Console.WriteLine("Validated SAML with certificate found in SAML" + SAMLMessageSignature.Verify(samlXml, certInSaml));
Console.WriteLine("Validated SAML with certificate file" + SAMLMessageSignature.Verify(samlXml, certInFile));

I'm getting true for everything above, except the last two. So:

  1. The SAML is valid
  2. The SAML has a valid signature
  3. The public key certificate in the SAML is the same as the certificate file we have
  4. The SAML is signed with the private key of neither the certificate file nor the public key sent in the SAML

From 3,4 can we conclude that Salesforce is signing but with a different certificate but sending the wrong public key in the response?!

Edit: Sample SAML is here http://pastebin.com/J8FTxnhJ

What am I missing?

Answer

ComponentSpace picture ComponentSpace · May 9, 2015

An XML signature verification fails either because the XML has been modified after signing or the wrong certificate is being used to verify the signature. The most likely scenario is that the wrong certificate is being used.

Salesforce signs the SAML response using their private key. Using the Salesforce admin console you can download the corresponding public key/certificate which should be used to perform the signature verification.

When calling SAMLMessageSignature.Verify, you can specify the X509Certificate to use to perform the verification which is typically what you should do.

However, the base-64 encoded X.509 certificate is also embedded in the XML signature. You can use this embedded certificate to check whether the signature verifies.

To do this, don't pass in an X509Certificate to SAMLMessageSignature.Verify.

For example: SAMLMessageSignature.Verify(samlXml, null);

If that works but specifying a certificate down't work then this confirms that the wrong certificate is being used.

You can call SAMLMessageSignature.GetCertificate to retrieve the X.509 certificate from the XML signature to compare it with the certificate being used.

Also, as a side note, XML signatures apply to XML. They cannot be directly verified using the base-64 encoded SAML response sent in the HTTP Post data. The post data must be decoded to XML prior to attempting to verify the XML signature.