What are the QR code fields that will be validated in the Integration phase starting from 1 January 2023 onwards?
The users will be able to validate the following fields:
- Seller’s Name.
- VAT registration number of the seller.
- Timestamp of the electronic invoice or credit/debit note (date and time).
- Electronic invoice or credit/debit note total (with VAT).
- VAT amount.
- Hash of XML electronic invoice or credit/debit note.
- Elliptic Curve Digital Signature Algorithm (ECDSA) signature.
- ECDSA public key: The public key BLOB format contains only the public portion of an ECDSA key used to generate the Cryptographic Stamp. Length of the public key BLOB for a 256-bit key is 64 bytes (72 bytes including magic number and field length information on some systems).
- For Simplified Tax Invoices and their associated notes, the ECDSA signature of the cryptographic stamp’s public key by ZATCA’s technical Certificate Authority (CA) is required.
- An ECDSA signature is encoded according to IEEE P1363. This signature format encodes the (r, s) tuple as the concatenation of the big endian representation of r and the big-endian representation of s.
- Each of these values is encoded using the number of bytes required to encode the maximum integer value in the key’s mathematical field.
- For example, an ECDSA signature from 256-bit elliptic curves (like secp256k1) encodes each of r and s as 32 bytes, and produces a signature output of 64 bytes. Please find below an example:
public static byte[] extractR(String digitalSignature) throws
Exception {
MessageDigest digest = MessageDigest.
getInstance(""SHA-256"");
byte[] hash =
digest.digest(Base64.getDecoder().
decode(digitalSignature.getBytes(StandardCharsets.
UTF_8)));
return Arrays.copyOfRange(hash, 0, 32);
}
/**
* Extract S Component
*
* @return
* @throws Exception
*/
public static byte[] extractS(String digitalSignature) throws
Exception {
MessageDigest digest = MessageDigest.
getInstance(""SHA-256"");
byte[] hash =
digest.digest(Base64.getDecoder().
decode(digitalSignature.getBytes(StandardCharsets.
UTF_8)));
return Arrays.copyOfRange(hash, 32, 64);