I am creating the xml for ZATCA einvoicing in python and i am stuck at step2 - generating digital signature and placing in the Signaturevalue tag .When i try to verify with zatca portal , it gives me the below error :
category : SIGNATURE_ERROR code :signatureValue message : wrong signature Value
Below is my code and the steps i am following in python :
f = ET.parse(xml_basic_out)
xslt = ET.parse(xml_transform_step1_xslt)
transform = ET.XSLT(xslt)
newdom = transform(f)
new_xml = ET.tostring(newdom,encoding ="utf-8") # Removed all spaces and comments from the original xml
# print(new_xml.decode())
xmldsig = chilkat2.XmlDSig()
canonXml = xmldsig.CanonicalizeXml(new_xml.decode(),"C14N",False)
invoice_hash_digest = sha256(canonXml.encode()).digest()
print(invoice_hash_digest)
invice_hash_digest_b64_encoded = base64.b64encode(invoice_hash_digest)
print(f'Invoice Hash base64 encoded : {invice_hash_digest_b64_encoded.decode("utf-8")}')
with open(modified_invoice_hash_stp1, 'wb+') as o:
o.write(invice_hash_digest_b64_encoded)
os.system('cmd /c'+'"'+openssl+'"'+' '+'dgst -sha256 -sign '+private_key+' -out ' +digital_signature_step2+' '+modified_invoice_hash_stp1)
with open(digital_signature_step2, 'rb') as f:
data = f.read()
sig_b64 = base64.b64encode(data)
print(f'Digital Signature base64 encoded : {sig_b64.decode("utf-8")}')
In the above code , im doing the following:
- reading the xml and Canonicalizing it
- Creating the hash of the xml and storing it in the file
- Signing the invoice hash (in bytes and not base64 encoded) with private key (pem) using openssl command
- encoding the final output in base64
After doing all the steps im getting the output something like this : 'MEUCIQCaBTUxgZU/c1l7iNGE+Kzn+Mboj2XtYUiwUQZe9D51awIgbA3sfvKonKDLzGLj03OqoxfL0cPiGYTqtoDkiZjcOaY='
The above is not matching with zatca's expected output. Can someone please help me?