I'm trying to add timestamp into XAdES digital signature in order to rise it to XAdES-T level. The problem is: how to calculate hash value of SIgnatureValue element to send it to TSA (timestamp authority) in order to get timestamp on it?
Below is part of my xml signature file with SignatureValue element and C# code used to calculate hash value. I've tried different methods (with PreserveWhitespace true or false, etc.), but calculated hash value is the same. Converted from byte[] to Base64 string: "Ai0lX2Kpgvf2qgnvgnZKN9neUCNGHjXI+XAsEwBzW8k="
Problem is: when we're validating created timestamp with other system, it states that timestamp is incorrect, because timestamped data has changed. After debugging we've found that another system is calculating different hash value of the same SignatureValue element: "XLwTMsF/Axb5/BI0Vvb8fKsJiVVRZmVILWCb/osTWC4="
If we hardcode that hash value into our code, then everything goes fine and created XAdES-T file with timestamp is validated correctly in another system. It's not possible to compare source code with another system because it's proprietary
and anyway it's created not on Microsoft platform (not .NET). They stated that our code for calculating hash value of SignatureValue element is incorrect and problem is most likely about canonization - referring to http://www.w3.org/TR/2001/REC-xml-c14n-20010315
and stating that canonization must be performed in the context of the whole document, not just SignatureValue element. But, as described in W3 XAdES-T specification (http://www.w3.org/TR/XAdES/#Syntax_for_XAdES_T_form):"the input for the timestamp hash computation is the ds:SignatureValue
XML element". Also, any samples and recommendations (we're able to find on the Internet for calculating timestamp) are using the same approach as in the
code sample below.
This is very urgent, could anyone help, please? Answer could be one of the following:
1. If code below for calculating hash value is incorrect, then what is correct way to get correct result?
or
2. If our code is correct, then another system is not conforming with standards - how could I verify and prove that?
Test code for calculating hash value of SignatureValue element:
var doc = new XmlDocument() { PreserveWhitespace = true }; doc.Load("signature_file.xml"); var docElement = doc.DocumentElement; var signatureValueXmlElement = docElement.GetElementsByTagName("SignatureValue")[0]; var signedInfoDoc = new XmlDocument { PreserveWhitespace = true}; signedInfoDoc.LoadXml(signatureValueNode.OuterXml); var canonization = new XmlDsigC14NTransform(); canonization.LoadInput(signedInfoDoc); SHA256 sha256 = SHA256.Create(); var tempHash = canonization.GetDigestedOutput(sha256);
Part of digital signature file ("signature_file.xml") with SignatureValue element:
<Signature ...><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod ...><Reference ...></Reference> ...</SignedInfo><SignatureValue Id="SignatureValue_Elem_0"> mnmqIMTVG/zflF60U5CKsCI8M9YwOOm09+ZcV1BZSSeYJq6FUD/Dj/tztp6pDmitCOSa33R/87wi uipRwZmT6H45PnRYFwHFBAt3fOjmkQ7CZr4tYCC2YFnEEOB3FFJVCy1BS46VG7yTa0KQVU/IgSFS lrR3WWuiBLBn9wwqN+26oERLXTvVR4nVKEdJBG67xCBGL5TJH2DdccnIe2eP0joVcTbkMebGV7F0 eYZ4us0wQeh3HvBF8feKP77eIGeMoF62Gx+2QU+s9VCLmFyglPfSXW9r/7W0UNTMuPrHG3lBalTl 2ULgzuB825pGe44rwPBSmhsL3SmNs6BAyeBA9A==</SignatureValue><KeyInfo><X509Data><X509Certificate> ...</X509Certificate></X509Data></KeyInfo><Object> ...</Object></Signature>