Decrypting a SAML Assertion in OpenSAML v3

As you probably should know at this point, the SAML Assertion contains the description of a authenticated user and how it was authenticated. The assertion is generally signed to prevent manipulation but there are also cases where you would want to encrypt the assertion to prevent someone to see the information within. For example the assertion can be used to communicate personal information about the user such as social security number and address.

As most people reading my blog seem to be on the SP side of SAML I will explain how to decrypt an assertion.

The general method of encryption and subsequent decryption of a assertion uses two keys, one symmetric and on asymmetric. The symmetric key is generated during encryption and used to encrypt the actual assertion data. An asymmetric key, generally a SP key contained in the metadata, is then used to encrypt the symmetric key which is then stored in the XML together with the encrypted assertion.

 1<?xml version="1.0"?>
 2<saml2p:response destination="http://localhost:8080/webprofile-ref-project/sp/consumer" id="_bd4528ed60f7b8142c39ee800625972f" issueinstant="2017-05-20T21:26:14.955Z" version="2.0">
 3  <saml2:issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">TestIDP</saml2:issuer>
 4  <saml2p:status>
 5    <saml2p:statuscode value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
 6  </saml2p:status>
 7  <saml2:encryptedassertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">
 8    <xenc:encrypteddata xmlns:xenc="http://www.w3.org/2001/04/xmlenc#" id="_2b077c659cdb0187fb617362135c3d63" type="http://www.w3.org/2001/04/xmlenc#Element">
 9      <xenc:encryptionmethod algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc">
10        <ds:keyinfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
11          <xenc:encryptedkey id="_24266af2ae292a886ee40085790ec5c4">
12            <xenc:encryptionmethod algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p">
13              <ds:digestmethod algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
14            </xenc:encryptionmethod>
15            <xenc:cipherdata>
16              <xenc:ciphervalue>THE ENCRYPTED SYMMETRIC KEY</xenc:ciphervalue>
17            </xenc:cipherdata>
18          </xenc:encryptedkey>
19        </ds:keyinfo>
20        <xenc:cipherdata>
21          <xenc:ciphervalue>THE ASSERTION ENCRYPTED USING THE SYMMETRIC KEY</xenc:ciphervalue>
22        </xenc:cipherdata>
23      </xenc:encryptionmethod>
24    </xenc:encrypteddata>
25  </saml2:encryptedassertion>
26</saml2p:response>

To decrypt the reverse of this is done. The asymmetric is used to decrypt the symmetric key, which is then used to decrypt the assertion.

Now for the OpenSAML part.

First we get the assertion from the XML. The assertion is stored in a EncryptedAssertion object and is retrieved with the method getEncryptedAssertions() on the response instead of getAssertions() which is used otherwise.

1StaticKeyInfoCredentialResolver keyInfoCredentialResolver 
2    = new StaticKeyInfoCredentialResolver(SPCredentials.getCredential());
3
4Decrypter decrypter 
5    = new Decrypter(null, keyInfoCredentialResolver, new InlineEncryptedKeyResolver());
6decrypter.setRootInNewDocument(true);
7
8decrypter.decrypt(encryptedAssertion);

In this example a StaticKeyInfoCredentialResolver is used to point out the key that is used for decryption, in this case I have stored it in the static class SPCredentials. The InlineEncryptedKeyResolver is used to tell the decrypter that the symmetric encryption key can be found in the XML next to the encrypted assertion.

The decrypter returns a decrypted Assertion object.

 1<?xml version="1.0"?>
 2<saml2:assertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="_96a918c84ff41a98781133414a7c930e" issueinstant="2017-05-20T21:26:14.956Z" version="2.0">
 3  <saml2:issuer>TestIDP</saml2:issuer>
 4  <ds:signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
 5    <ds:signedinfo>
 6      <ds:canonicalizationmethod algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
 7        <ds:signaturemethod algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1">
 8          <ds:reference uri="#_96a918c84ff41a98781133414a7c930e">
 9            <ds:transforms>
10              <ds:transform algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature">
11                <ds:transform algorithm="http://www.w3.org/2001/10/xml-exc-c14n#">
12                  <ec:inclusivenamespaces xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#" prefixlist="xsd"></ec:inclusivenamespaces>
13                </ds:transform>
14              </ds:transform>
15            </ds:transforms>
16            <ds:digestmethod algorithm="http://www.w3.org/2001/04/xmlenc#sha256">
17              <ds:digestvalue>UDJ762cOSK14nBjbFCq9a47x3WgSCJ1qZpeBYKdy5s0=</ds:digestvalue>
18            </ds:digestmethod>
19          </ds:reference>
20        </ds:signaturemethod>
21      </ds:canonicalizationmethod>
22    </ds:signedinfo>
23    <ds:signaturevalue>
24syb20Rjh1pDJTc6CY1nN3x1v8WNlG9lRf71A5ik3i97/A+q0NZCvoJLEBVM73K/U8hxo/hbHOmBs
257KkF4g3yYLVunRlm/tapnTESKqZ8v8SJZQcbY4xMzi0PUxiUJKBugiho114ijDPAYs+U1UZhXGHL
26zyHVd7XJYoOATKVdh3U=
27</ds:signaturevalue>
28  </ds:signature>
29  <saml2:subject>
30    <saml2:nameid format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient" namequalifier="Name qualifier" spnamequalifier="SP name qualifier">Some NameID value</saml2:nameid>
31    <saml2:subjectconfirmation method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
32      <saml2:subjectconfirmationdata inresponseto="Made up ID" notbefore="2017-05-18T21:26:14.957Z" notonorafter="2017-05-22T21:26:14.957Z" recipient="http://localhost:8080/webprofile-ref-project/sp/consumer"></saml2:subjectconfirmationdata>
33    </saml2:subjectconfirmation>
34  </saml2:subject>
35  <saml2:conditions notbefore="2017-05-18T21:26:14.958Z" notonorafter="2017-05-22T21:26:14.958Z">
36    <saml2:audiencerestriction>
37      <saml2:audience>http://localhost:8080/webprofile-ref-project/sp/consumer</saml2:audience>
38    </saml2:audiencerestriction>
39  </saml2:conditions>
40  <saml2:attributestatement>
41    <saml2:attribute name="username">
42      <saml2:attributevalue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">bob</saml2:attributevalue>
43    </saml2:attribute>
44    <saml2:attribute name="telephone">
45      <saml2:attributevalue xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">999999999</saml2:attributevalue>
46    </saml2:attribute>
47  </saml2:attributestatement>
48  <saml2:authnstatement authninstant="2017-05-20T21:26:14.962Z">
49    <saml2:authncontext>
50      <saml2:authncontextclassref>urn:oasis:names:tc:SAML:2.0:ac:classes:Smartcard</saml2:authncontextclassref>
51    </saml2:authncontext>
52  </saml2:authnstatement>
53</saml2:assertion>