Adding KeyInfo to a message in OpenSAML

When a message is signed with a private key, the receiving end will need to verify the message using the corresponding public key/certificate. But in order to do this, the receiving end must have the certificate.

The certificate is transported in encoded form in a KeyInfo element. Below is a example

 1<ds:keyinfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
 2        <ds:x509data>
 3          <ds:x509certificate>
 4          MIICizCCAfQCCQCY8tKaMc0BMjANBgkqhkiG9w0BAQUFADCBiTELMAkGA1UEBhMCTk8x
 5          EjAQBgNVBAgTCVRyb25kaGVpbTEQMA4GA1UEChMHVU5JTkVUVDEOMAwGA1UECxMFRmVp
 6          ZGUxGTAXBgNVBAMTEG9wZW5pZHAuZmVpZGUubm8xKTAnBgkqhkiG9w0BCQEWGmFuZHJl
 7          YXMuc29sYmVyZ0B1bmluZXR0Lm5vMB4XDTA4MDUwODA5MjI0OFoXDTM1MDkyMzA5MjI0
 8          OFowgYkxCzAJBgNVBAYTAk5PMRIwEAYDVQQIEwlUcm9uZGhlaW0xEDAOBgNVBAoTB1VO
 9          SU5FVFQxDjAMBgNVBAsTBUZlaWRlMRkwFwYDVQQDExBvcGVuaWRwLmZlaWRlLm5vMSkw
10          JwYJKoZIhvcNAQkBFhphbmRyZWFzLnNvbGJlcmdAdW5pbmV0dC5ubzCBnzANBgkqhkiG
11          9w0BAQEFAAOBjQAwgYkCgYEAt8jLoqI1VTlxAZ2axiDIThWcAOXdu8KkVUWaN/SooO9O
12          0QQ7KRUjSGKN9JK65AFRDXQkWPAu4HlnO4noYlFSLnYyDxI66LCr71x4lgFJjqLeAvB/
13          GqBqFfIZ3YK/NrhnUqFwZu63nLrZjcUZxNaPjOOSRSDaXpv1kb5k3jOiSGECAwEAATAN
14          BgkqhkiG9w0BAQUFAAOBgQBQYj4cAafWaYfjBU2zi1ElwStIaJ5nyp/s/8B8SAPK2T79
15          McMyccP3wSW13LHkmM1jwKe3ACFXBvqGQN0IbcH49hu0FKhYFM/GPDJcIHFBsiyMBXCh
16          pye9vBaTNEBCtU3KjjyG0hRT2mAQ9h+bkPmOvlEo/aH0xR68Z9hw4PF13w==
17          </ds:x509certificate>
18        </ds:x509data>
19      </ds:keyinfo>

There are many ways to give the receiving end the certificate. Two common methods is metadata and in the message.

When using the metadata method the KeyInfo object is embedded in the metadata inside the KeyDescriptor element. When attaching KeyInfo to the SAML message the element is embedded in the Signature object.

To create and add a KeyInfo object and add it to a SAML message signature, add this call to SecurityHelper before generating the signature.

1SecurityHelper.prepareSignatureParams(signature, IDPCredentials.getCredential(),
2                    Configuration.getGlobalSecurityConfiguration(), null);

This helper method does not only add a the key info but it also sets the

  • Signature algorithm URI
  • Canonicalization algorithm URI
  • and HMAC output length (if applicable and a value is configured)

Customizing the KeyInfo

The above statement only uses the default configuration of for generating KeyInfo. To customize the KeyInfo you create your own instance of KeyInfoGeneratorFactory, set it up as preferred and use it in the statement.

The example below shows how to use a X509KeyInfoGeneratorFactory to create a KeyInfo with properties from the X509 certificate used as credential.

1X509KeyInfoGeneratorFactory x509Factory = new X509KeyInfoGeneratorFactory();
2x509Factory.setEmitEntityCertificate(true);
3x509Factory.setEmitEntityCertificateChain(true);
4x509Factory.setEmitX509IssuerSerial(true);
5x509Factory.setEmitX509SubjectName(true);
6 
7Configuration.getGlobalSecurityConfiguration().getKeyInfoGeneratorManager().registerFactory("x509emitingKeyInfoGenerator", x509Factory);
8 
9SecurityHelper.prepareSignatureParams(signature, SPCredentials.getCredential(), null,  "x509emitingKeyInfoGenerator");