SAML Single Logout (SLO) Signature Issues

Problem

You have setup a website to use SAML Single Logout (SLO), but SLO fails. PortalGuard's IdP log says the signature on the SLO request from the website is invalid.

Solution

Digital signatures offer the utmost security, but are very unforgiving if the signature is not created in the correct way. Signatures ensure three things:

  1. Authentication - Data is coming from an identifiable party

  2. Integrity - Data has not been modified in transit

  3. Non-repudiation - The signing party cannot claim it did not send the data

Creating a "signature" is composed of two main steps: 1) Running the data to be signed through a hash algorithm like SHA-1 or SHA-256, and 2) encrypting that hash value with a private key. Now any other party with the public key can be assured of the 3 points described above if the signature matches.

Misplacement of a single character, re-ordering of data going into the hash algorithm or an extra level of encoding will cause subsequent signature verification by the recipient to fail. Use of the Redirect (or GET) binding in SAML SLO uses something called "detached" signatures which is the topic of this KB. The technical details of detached signatures in SAML are defined in section 3.4.4.1 of the SAML 2.0 Bindings specification (for those of you who enjoy reading specs!).

For our purposes, verification of a SAML SLO signature requires the following:

  1. The public signing certificate from the Service Provider/app (retrieval info below)

  2. The raw HTTP GET request to PortalGuard's SAML SLO handler, e.g.: https://<your.pg.server>/sso/slo.ashx

  3. openssl.exe - The defacto opensource cryptographic implementation. You can download an older, pre-compiled copy here. This is a command-line program so launch a Command Prompt to use it.

The steps to verify a SAML SLO signature are below. All files involved in these steps (including openssl.exe and openssl.cnf) will be saved in the same directory for simplicity.

1) Find the signing certificate

This can typically be retrieved from the entity's SAML metadata. The base64-encoded version can be found in the X509Certificate element. There are often multiple elements with this name, so choose the one which is a child element of the KeyDescriptor element with the use="signing" attribute. The green highlighted text in the image below shows the certificate value:

HINT: Both the KeyDescriptor and X509Certificate element often have a namespace "prefix" in front of them (e.g. md: or dsig:)

HINT 2: Only copy the value between the X509Certificate opening and closing tags. Do NOT include the tags themselves!

In a text editor, copy this value into a new file named spsign.cer and ensure the file has the "BEGIN" and "END" markers as shown below: -----BEGIN CERTIFICATE----- <base64-encoded cert> -----END CERTIFICATE-----

NOTE: It does not matter if the encoded certificate is one or multiple lines!

As a confirmation, double-clicking the resulting spsign.cer file in Windows should show the details of the certificate itself:

2) Extract binary public key from certificate

Openssl requires the binary public key as part of the verification. This is extracted from the .cer file you just created with the following DOS command:

openssl x509 -pubkey -noout -in spsign.cer > spsign.pub

You should now have a file named spsign.pub in the same folder as the spsign.cer.

3) Extract the base64-encoded signature value You will do this step manually. Using a HTTP trace utility like Fiddler or the Network trace in your browser's built-in Developer Tools, find the HTTP request containing the SAML SLO request. To help identify this, PortalGuard's SAML SLO URL is /sso/slo.ashx. You want the portion of the URL that starts with &Signature= as shown below:

This value must be URL decoded which can be done from many different online utilities (link1, link2, link3).

Copy this decoded value to a new file named sig.txt and save it:

The last step with this signature is to convert it to a binary file named sig.bin using the following DOS command:

openssl base64 -d -A -in sig.txt -out sig.bin

You should now have the following newly-created files in the same folder:

  • spsign.pub

  • sig.txt

  • sig.bin

4) Create the input file

The penultimate step before actually verifying the signature is creating a file that will contain the data to be signed. For SAML SLO, this is taken from the query string of the same request where you pulled the Signature value in the last section. The "query string" is all the values in a URL that come after the ? character. The values to be taken from the request URL must be taken in the following order:

  1. SAMLRequest

  2. RelayState - (Optional - this value may not be present)

  3. SigAlg

These values should be taken as-is from the raw request URL. They must NOT be URL-decoded!

There was no RelayState in the original request so the resulting file only contains two parameters: SAMLRequest and SigAlg

Note that SigAlg (and RelayState if it were present) have a leading & character before their name! SAMLRequest is the first parameter so you do NOT add an &.

5) Verify the digital signature

This final step will actually perform all the steps of verifying a signature based on the data provided, the hash algorithm used and the signing party's public key. The following DOS command checks a SHA-256 signature:

openssl dgst -sha256 -verify spsign.pub -signature sig.bin inp.txt

If the signature used SHA-1, then use the -sha1 parameter instead:

Use the SigAlg value to determine which algorithm to use:

  • SHA1 - SigAlg=http%3A%2F%2Fwww.w3.org%2F2000%2F09%2Fxmldsig%23rsa-sha1

  • SHA256 - SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256

If the signature is correct, openssl.exe outputs "Verified OK". If it fails, it returns "Verification Failed". Here are examples:

Hopefully, this served as a helpful walk-through of detached digital signatures and how they can be verified. If you run into any errors or have questions, please email us at techsupport@portalguard.com.