如何在 PHP 中将 Base64 解码为 TLV

How to Decode Base64 to TLV in PHP

我正在为我的公司构建一个内部发票解决方案。政府要求我们创建以标签长度值 (TLV) 格式编码的二维码字段。

TLV编码如下:

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.

在示例中,他们提供了这个 Base64 输出

AQkxMjM0NTY3ODkCCjEyLzEyLzIwMjADBDEwMDADAzE1MPaIn2Z2jg6VqWvWV6IrZZNzLF7xvZrWXW5xRV5yFY2xFu0ycXOiyqV0k7Wsh6b1IcE2Tfzap1AQAQVsktmsv1FFQ1MxIAAAAGKblFMh9nFRSn8tvftXqo9zRSz2VEAPITSZ3W7UDHKhUx+7yXGijLtJSZGXMOc+jpKwARzDl68GmmRd75NWdOs=

当我解码时使用

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

我得到的回复是:

    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�

标签 1:卖家名称

标签 2:增值税注册号

标记 3:发票的时间戳

标记 4:发票总计

标签 5:税收总额

标签 6:XML 发票的哈希值

标签 7:ECDSA 签名

标签 8:ECDSA Public 密钥

标签 9:加密戳的 public 密钥的 ECDSA 签名

我在这里做错了什么,正确的语法是什么?

知道它是二进制数据,我们可以用 bin2hex(base64_decode($base64)) 回显它,然后看到这个:

0109313233343536373839020a31322f31322f323032300304313030300303313530f6889f66768e0e95a96bd657a22b6593732c5ef1bd9ad65d6e71455e72158db116ed327173a2caa57493b5ac87a6f521c1364dfcdaa7501001056c92d9acbf514543533120000000629b945321f671514a7f2dbdfb57aa8f73452cf654400f213499dd6ed40c72a1531fbbc971a28cbb4949919730e73e8e92b0011cc397af069a645def935674eb

为了方便查看,我使用了命令行工具base64 -dxxd来获得这个视图:

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.

您没有解释可能的“标签”值是什么,但我可以看到该字符串的开头有一个标签 0x01、长度 0x09,以及以下内容9 个字节是 ASCII/UTF-8 for 123456789;然后它有一个标签 0x02,长度 0x0a,接下来的 10 个字符是 ASCII/UTF-8 12/12/2020;等等。

后面有一个f6的标签,长度为88,还有一些二进制数据,但不知道标签f6是什么意思,我没有理由假设这是一个问题 - 也许它嵌入了图像或压缩数据流。

已编辑:

Security Specification 中说:

4.2 Structure of the Cryptographic Stamp applied on the QR code The below specifications of the Cryptographic Stamp required for the QR code are based Annex (2) of the Controls, Requirements, Technical Specifications and Procedural Rules for Implementing the Provisions of the E-Invoicing Regulation. The QR code Cryptographic Stamp shall be generated use the same digital certificate used for stamping the electronic invoices. Please refer to section 3 for the requirements applicable to the management and use of digital certificates used to apply Cryptographic Stamp on electronic invoices. The Cryptographic Stamp shall be applied on the entire TLV encoding of the QR code fields (from tag 1 to tag 6) then it shall be appended to the TLV structure. The Cryptographic Stamp consists of two fields as shown in the below table:

我假设这部分数据是加密戳的一部分

For Decode QR Code (Zatca) in PHP

  1. 读取二维码 - 示例 base64 代码。
  2. 解码base64代码。
  3. 使用 preg_replace 从字符串中删除 unicode 值
  4. 并分解得到数组

Sample code

$base64 = "AQZSYWZlZXECDTEyMzQ1Njc4OVQxMjUDFDIwMjEtMDctMTJUMTQ6MjU6MDlaBAM3ODYFAjI1";

$decoded = base64_decode($base64);

//print_r($decoded)
//raw data
//\u0001\u0006Rafeeq\u0002\t123456789\u0003\u00142021-07-12T14:25:09Z\u0004\u0003786\u0005\u000225

$result_data = preg_replace('/[\x00-\x1F\x80-\xFF]/', ',', $decoded);

$actula_data = explode(',,', $result_data);

print_r($actula_data);

Output :

["","Rafeeq","123456789T125","2021-07-12T14:25:09Z","786","25"]