python-3.xopensslxmlsec

Digest value generated in xmlsec and openssl are different


Hi I'm learning and working on digital signature verification and I tried using xmlsec library. Using xmlsec and the code from the example:

parser = etree.XMLParser(remove_blank_text=True)
template = etree.parse('test.xml', parser).getroot()

signature_node = xmlsec.tree.find_node(template, xmlsec.constants.NodeSignature)
ctx = xmlsec.SignatureContext()
key = xmlsec.Key.from_file('keys/private_key.pem', xmlsec.constants.KeyDataFormatPem)
ctx.key = key
ctx.sign(signature_node)
formated = etree.tostring(template)

with open('xmlsec_formatted.xml', 'wb') as the_file:
    the_file.write(formated)

It generated a a new file with the digest value of: izbIdQ4tSAg6VKGpr1zd6kU9QpVQi/Bcwxjxu/k2oKk=

I tried to reproduce this value just to see if I understood it correctly. As from this question. My understanding is that after canonicalizing the xml (I used below code)

from lxml import etree

parser = etree.XMLParser(remove_blank_text=True)

xmlTree = etree.parse('test.xml', parser)
root = xmlTree.getroot()
formated = etree.tostring(root, method='c14n')
with open('canon.xml', 'wb') as the_file:
        the_file.write(formated)

I just needed to hash it and encode it to base64. From another question, I tried the following openssl command: openssl dgst -binary -sha256 canon.xml | openssl enc -base64. However, it produced this digest value: YAzI0t93fuMTBIGkLeYC5VVPyaM0FziBLP5fF6qojbw= I also tried using the initial xml file but it still produces a different value. Is my understanding correct? How can I verify the Digest Value for learning purposes.


Solution

  • I was doing it wrong after reading: RFC3274

    I needed to decode the obj element and not the actual xml file itself. After decoding the obj element and applying the proper hash I got the same result.