XML Signature: How to calculate the digest value? XML Signature: How to calculate the digest value? xml xml

XML Signature: How to calculate the digest value?


I came across this question when attempting to find out the exact same thing. I later worked out how to do it, so figured I'd post the answer here.

The things that need to happen are:

  • canonicalization
  • create digest value, typically SHA1 (but could be SHA256 amongst others)
  • base64 encode it

The canonicalization part was fairly simple, as the Java libraries did that for me. What I struggled with was the next bit, the creating of the digest, because I made a fatal error in that the SHA1 digest I generated was the SHA1 in HEX form. SHA1 is 160 bits, so 20 bytes, but if you output these 160 bits in HEX, you get 40 characters. If you then base64 encode that, you get totally the wrong value compared to what should be in the DigestValue.

Instead, you should generate the SHA1 digest and base64 encode the 20 byte output. Don't try to output the 20 bytes to STDOUT as it's highly unlikely to be readable (which is why people often output the HEX equivalent, since it is readable). Instead, just base64 encode the 20 bytes and that's your DigestValue.


Is very simple, use openssl in the console:

openssl dgst -binary -sha1 file | openssl enc -base64

Done


I have encountered exactly this problem myself: I was generating an XML signature in Java & validating in .NET, and the validation always failed. In my case the cause was the 'print XML to file' function XMLWrite.m (yes, in MATLAB*) which was 'pretty printing' the XML, inserting tabs, spaces, and newlines as it saw fit. Since these are part of the document, naturally the validation failed (it failed in Java, too). Looking at your source, this may be happening to you. Use a Transformer (javax.xml.transform.*) to serialise your DOM properly without changing the content.

*You did know that MATLAB understands Java as well? You can just type Java statements into the interpreter console & they will be executed like native m-code.