Monday, November 12, 2012

Signing with OpenSAML

When exchanging information with SAML it is highly recomended to sign and verify signatures on all messages. This to ensure the the sender really is how he says he is and that the information sent has not been manipulated during transport.

Every SAML object that implements the SignableXMLObject interface can be signed.

The signing of a SAML message is done in three steps. First, all the properties for the signature is put in a Signature object. Properties that can be set include singing credentials, algorithm and optionally a KeyInfo object. The KeyInfo object identifies what key should be used to verify the signature.
The Signature object is then added to the SAML object using the setSignature method.
entityDescriptor.setSignature(signature); The second step is to marchal the object. This must be done before signing or else you will get a message like this.

SEVERE: Unable to compute signature, Signature XMLObject does not have the XMLSignature created during marshalling.

Element element = Configuration.getMarshallerFactory().getMarshaller(entityDescriptor).marshall(entityDescriptor);
The third step is to perform the actual signing to produce a cryptographic signature, this is done with the Signer class.
Here is how the signed object might look after signing and marshalling.


Further reading

My book, A Guide to OpenSAML, explains in detail how to use the security features of SAML.
A Guide to OpenSAML V3


  1. After putting Signer.signObject(signature);
    I am getting

    Signature object is not initialized properly.

  2. Hi Stefan ...

    How are you outputting the Response XML? I can create an Assertion without issue, and output its XML, but when I try to get a Response output, the Signature is being destroyed.

    I have the following code snippets.


    void signObject(SignableXMLObject object) throws Exception
    SecurityConfiguration secConfig = Configuration.getGlobalSecurityConfiguration();
    Signature signature = createSAMLObject(Signature.class);
    SecurityHelper.prepareSignatureParams(signature, signingCredential, secConfig, null); //Is this even necessary?



    Document asDOMObject(XMLObject object) throws Exception
    Document document = builder.newDocument ();
    Marshaller out = Configuration.getMarshallerFactory().getMarshaller(object);
    out.marshall(object, document);
    return document;

    // code to create an assertion

    // code to create a response with the assertion

    //At this point, both objects have valid XMLSignatures ... I can see this using a debugger.

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    new DOMSource(asDOMObject(assertion)), new StreamResult(buffer));
    byte[] rawResult = buffer.toByteArray();

    String xmlResult = new String(rawResult);"Assertion:");;

    //The Assertion gets output without an issue ... the signature values are all in tact.

    buffer = new ByteArrayOutputStream();
    new DOMSource(asDOMObject(response)), new StreamResult(buffer));

    //Immediately after the above line is executed, the XMLSignature is changed and the original values are lost. Why?

    rawResult = buffer.toByteArray ();

    xmlResult = new String(rawResult);"Response:");;

    I've tried a slightly different approach, but I think it's basically the same thing ...

    ResponseMarshaller responseMarshaller = new ResponseMarshaller();
    Element plain = responseMarshaller.marshall(response);
    xmlResult = XMLHelper.nodeToString(plain);

    This code also results in the Response's XMLSignature to be destroyed when it is marshalled.

    Any assistance you can provide would be very much appreciated. Thanks so much for looking at this.

  3. Hi Stefan,

    I posted a question yesterday (I think it was under this page's topic - Signing With OpenSAML), but I don't see my question here today.

    The detailed version of my question is here:

    I am hoping that you can help me with my situation.

    Thank you!


    1. I have answered your question on stackoverflow. Hope it helps.