Skip to main content

Even more XML Signature debugging tips

Posted by mullan on August 3, 2007 at 9:19 AM PDT

In a previous blog entry, I wrote about how to enable logging to get debugging output when using the Java XML DSig API to validate an XML Signature. There are also various methods in the API that you can invoke to get similar information. Here are a couple of those which are probably most useful:

  1. SignedInfo.getCanonicalizedData

    This method will return an InputStream containing the canonicalized bytes of the SignedInfo element. This method is very useful for debugging signature verification failures; often these are due to subtle changes in the canonicalized bytes, such as XML marshallers that format or "pretty-print" the XML, inserting newlines and other whitespace that break the signature. Here's an example of how to use this API:

    System.out.println("Canonicalized SignedInfo:");
    InputStreamReader isr = 
        new InputStreamReader(si.getCanonicalizedData());
    char[] cbuf = new char[1024];
    while (isr.read(cbuf, 0, 1024) != -1) {
        System.out.print(cbuf);
    }
    System.out.println();
    

    You should compare the SignedInfo element that is output with the SignedInfo element in the Signature.

  2. Reference.getDigestInputStream

    This method returns the Reference's pre-digested input stream. Because this data can be potentially large and expensive to keep in memory, you must first enable reference caching. The data returned is the input to the digest operation during a validation or signing operation. This method is very useful for debugging reference validation failures as well as showing the user exactly what was signed, which is very important. The usage of this API is similar to SignedInfo.getCanonicalizedData:

    // enable reference caching in your validation context 
    valContext.setProperty
        ("javax.xml.crypto.dsig.cacheReference", Boolean.TRUE);
    System.out.println("Pre-digested Input:");
    InputStreamReader isr = 
        new InputStreamReader(ref.getDigestInputStream());
    char[] cbuf = new char[1024];
    while (isr.read(cbuf, 0, 1024) != -1) {
        System.out.print(cbuf);
    }
    System.out.println();
    
    Related Topics >>