What is the process of generating certificate hash? Page 5 of <SigningProcessUpdated.pdf> describes:
- Hash the x509 certificate using SHA-256 (output).
e.g.:69a95fc237b42714dc4457a33b94cc452fd9f110504c683c401144d9544894fb
- Encode the hashed x509 certificate using base64 (ENCODER BASE64 ) (output).
e.g.:NjlhOTVmYzIzN2I0MjcxNGRjNDQ1N2EzM2I5NGNjNDUyZmQ5ZjExMDUwNGM2ODNjNDAxMTQ0ZDk1NDQ4OTRmYg==
Why does the length of the HASH encoded by BASE64 become 88? Or where can I find more detailed step-by-step instructions?
Dear @zeimao77,
Thanks for reaching out.
*Please check the signing process on the technical guidelines (1st step is how to generate the hash):https://zatca.gov.sa/en/E-Invoicing/Introduction/Guidelines/Documents/E-invoicing-Detailed-Technical-Guideline.pdf 102
if the invoice is standard:**after hashing the invoice hash using: fatoora -generatehash -invoice [name.xml], you should edit it manually in the first “digestvalue” tag which represents the invoice hash in the XML
if the invoice is simplified : sign the invoice using SDK through this command : fatoora -sign -invoice [name.xml]
this step will edit the invoice hash inside the XML automatically & will generate a new invoice with the suffix [_signed]
Thanks.
Thank you very much for your reply;
I have implemented steps 1 and 2 of the signature OK, but now I have no way to implement step 3 (page 53 of the document);
The result of the HASH256 summary is BASE64 encoded, and the length should be only 44 bits; I don’t understand how the algorithm for step 3 should be implemented;
javacode:
String c = "MIID3jCCA4SgAwIBAgITEQAAOAPF90Ajs/xcXwABAAA4AzAKBggqhkjOPQQDAjBiMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxEzARBgoJkiaJk/IsZAEZFgNnb3YxFzAVBgoJkiaJk/IsZAEZFgdleHRnYXp0MRswGQYDVQQDExJQUlpFSU5WT0lDRVNDQTQtQ0EwHhcNMjQwMTExMDkxOTMwWhcNMjkwMTA5MDkxOTMwWjB1MQswCQYDVQQGEwJTQTEmMCQGA1UEChMdTWF4aW11bSBTcGVlZCBUZWNoIFN1cHBseSBMVEQxFjAUBgNVBAsTDVJpeWFkaCBCcmFuY2gxJjAkBgNVBAMTHVRTVC04ODY0MzExNDUtMzk5OTk5OTk5OTAwMDAzMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEoWCKa0Sa9FIErTOv0uAkC1VIKXxU9nPpx2vlf4yhMejy8c02XJblDq7tPydo8mq0ahOMmNo8gwni7Xt1KT9UeKOCAgcwggIDMIGtBgNVHREEgaUwgaKkgZ8wgZwxOzA5BgNVBAQMMjEtVFNUfDItVFNUfDMtZWQyMmYxZDgtZTZhMi0xMTE4LTliNTgtZDlhOGYxMWU0NDVmMR8wHQYKCZImiZPyLGQBAQwPMzk5OTk5OTk5OTAwMDAzMQ0wCwYDVQQMDAQxMTAwMREwDwYDVQQaDAhSUlJEMjkyOTEaMBgGA1UEDwwRU3VwcGx5IGFjdGl2aXRpZXMwHQYDVR0OBBYEFEX+YvmmtnYoDf9BGbKo7ocTKYK1MB8GA1UdIwQYMBaAFJvKqqLtmqwskIFzVvpP2PxT+9NnMHsGCCsGAQUFBwEBBG8wbTBrBggrBgEFBQcwAoZfaHR0cDovL2FpYTQuemF0Y2EuZ292LnNhL0NlcnRFbnJvbGwvUFJaRUludm9pY2VTQ0E0LmV4dGdhenQuZ292LmxvY2FsX1BSWkVJTlZPSUNFU0NBNC1DQSgxKS5jcnQwDgYDVR0PAQH/BAQDAgeAMDwGCSsGAQQBgjcVBwQvMC0GJSsGAQQBgjcVCIGGqB2E0PsShu2dJIfO+xnTwFVmh/qlZYXZhD4CAWQCARIwHQYDVR0lBBYwFAYIKwYBBQUHAwMGCCsGAQUFBwMCMCcGCSsGAQQBgjcVCgQaMBgwCgYIKwYBBQUHAwMwCgYIKwYBBQUHAwIwCgYIKoZIzj0EAwIDSAAwRQIhALE/ichmnWXCUKUbca3yci8oqwaLvFdHVjQrveI9uqAbAiA9hC4M8jgMBADPSzmd2uiPJA6gKR3LE03U75eqbC/rXA==";
byte[] sha256s = DigestUtil.digest(c.getBytes(), ZatcaConst.DIGEST_ALGORITHM); // DIGEST_ALGORITHM = "SHA256";
String s1 = ByteArrayCoDesUtil.hexEncode(sha256s);
System.out.println("gened HASH3:"+ByteArrayCoDesUtil.base64Encode(s1.getBytes()));
sha256s = DigestUtil.digest(ByteArrayCoDesUtil.base64Decode(c), ZatcaConst.DIGEST_ALGORITHM);
String s4 = ByteArrayCoDesUtil.hexEncode(sha256s);
System.out.println("gened HASH4:"+ByteArrayCoDesUtil.base64Encode(s4.getBytes()));
System.out.println("right HASH5:ZDMwMmI0MTE1NzVjOTU2NTk4YzVlODhhYmI0ODU2NDUyNTU2YTVhYjhhMDFmN2FjYjk1YTA2OWQ0NjY2MjQ4NQ==");
output:
gened HASH3:RDMwMkI0MTE1NzVDOTU2NTk4QzVFODhBQkI0ODU2NDUyNTU2QTVBQjhBMDFGN0FDQjk1QTA2OUQ0NjY2MjQ4NQ==
gened HASH4:QTI4NkQyODdCMjRGRkZDMDUyQkJFMjAwQjEwQ0IzQjNFRUU0RTU4RDIxQzlENDdGRTQwQjk0NjQ0Qzc1NzA2OQ==
right HASH5:ZDMwMmI0MTE1NzVjOTU2NTk4YzVlODhhYmI0ODU2NDUyNTU2YTVhYjhhMDFmN2FjYjk1YTA2OWQ0NjY2MjQ4NQ==
This is the example step 3 provided in the official JDK website (certificate signing on page 53 of the document). How should the certificate be implemented? What is the definition of the certificate? Are there specific requirements for format and encoding?