Skip to content
Advertisement

How to Decode Base64 to TLV in PHP

I am building an inhouse Invoicing solution for my company. The government requires us to create QR Code fields encoded in Tag-Length-Value (TLV) format.

The TLV encoding shall be as follows:

Tag: the tag value as mentioned above stored in one byte

Length: the length of the byte array resulted from the UTF8 encoding of the field value. The length shall be stored in one byte.

Value: the byte array resulting from the UTF8 encoding of the field value.

In the example they have provided this Base64 Output

AQkxMjM0NTY3ODkCCjEyLzEyLzIwMjADBDEwMDADAzE1MPaIn2Z2jg6VqWvWV6IrZZNzLF7xvZrWXW5xRV5yFY2xFu0ycXOiyqV0k7Wsh6b1IcE2Tfzap1AQAQVsktmsv1FFQ1MxIAAAAGKblFMh9nFRSn8tvftXqo9zRSz2VEAPITSZ3W7UDHKhUx+7yXGijLtJSZGXMOc+jpKwARzDl68GmmRd75NWdOs=

When I decode using

$base64 = "AQkxMjM0NTY3ODkCCjEyLzEyLzIwMjADBDEwMDADAzE1MPaIn2Z2jg6VqWvWV6IrZZNzLF7xvZrWXW5xRV5yFY2xFu0ycXOiyqV0k7Wsh6b1IcE2Tfzap1AQAQVsktmsv1FFQ1MxIAAAAGKblFMh9nFRSn8tvftXqo9zRSz2VEAPITSZ3W7UDHKhUx+7yXGijLtJSZGXMOc+jpKwARzDl68GmmRd75NWdOs=";
echo base64_decode($base64); 

The response i get is:

    123456789
12/12/20201000150���fv���k�W�+e�s,^��]nqE^r���2qs�ʥt������!�6M�ڧPl�٬�QECS1 b��S!�qQJ-��W��sE,�T@!4��n�r�S��q���II��0�>���×��d]�Vt�

Tag 1: Seller’s Name

Tag 2: Vat Registration number

Tag 3: Timestamp of the invoice

Tag 4: Invoice Total

Tag 5: Tax Total

Tag 6: Hash of XML invoice

Tag 7: ECDSA Signature

Tag 8: ECDSA Public Key

Tag 9: ECDSA signature of the cryptographic stamp’s public key

What Am I doing wrong here and what is the right syntax to correct it?

Advertisement

Answer

Knowing it’s binary data, we can echo it with bin2hex(base64_decode($base64)), and see this:

0109313233343536373839020a31322f31322f323032300304313030300303313530f6889f66768e0e95a96bd657a22b6593732c5ef1bd9ad65d6e71455e72158db116ed327173a2caa57493b5ac87a6f521c1364dfcdaa7501001056c92d9acbf514543533120000000629b945321f671514a7f2dbdfb57aa8f73452cf654400f213499dd6ed40c72a1531fbbc971a28cbb4949919730e73e8e92b0011cc397af069a645def935674eb

For easier viewing, I used the command line tools base64 -d and xxd to get this view:

00000000: 0109 3132 3334 3536 3738 3902 0a31 322f  ..123456789..12/
00000010: 3132 2f32 3032 3003 0431 3030 3003 0331  12/2020..1000..1
00000020: 3530 f688 9f66 768e 0e95 a96b d657 a22b  50...fv....k.W.+
00000030: 6593 732c 5ef1 bd9a d65d 6e71 455e 7215  e.s,^....]nqE^r.
00000040: 8db1 16ed 3271 73a2 caa5 7493 b5ac 87a6  ....2qs...t.....
00000050: f521 c136 4dfc daa7 5010 0105 6c92 d9ac  .!.6M...P...l...
00000060: bf51 4543 5331 2000 0000 629b 9453 21f6  .QECS1 ...b..S!.
00000070: 7151 4a7f 2dbd fb57 aa8f 7345 2cf6 5440  qQJ.-..W..sE,.T@
00000080: 0f21 3499 dd6e d40c 72a1 531f bbc9 71a2  .!4..n..r.S...q.
00000090: 8cbb 4949 9197 30e7 3e8e 92b0 011c c397  ..II..0.>.......
000000a0: af06 9a64 5def 9356 74eb                 ...d]..Vt.

You haven’t explained what the possible “tag” values are, but I can see the start of that string has a tag of 0x01, a length of 0x09, and the following 9 bytes are ASCII/UTF-8 for 123456789; it then has a tag of 0x02, a length of 0x0a, and the next 10 characters are ASCII/UTF-8 12/12/2020; and so on.

Later, there is a tag of f6 with a length of 88, and some binary data, but without knowing what tag f6 means, I’ve no reason to suppose that’s a problem – maybe it embeds an image, or a stream of compressed data.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement