返回

如何解决 ZATCA 电子发票数字证书 base64 编码问题?

python

解决 ZATCA 电子发票数字证书 base64 编码问题:详细指南

引言

生成符合 ZATCA 规范的电子发票需要使用正确的数字证书 base64 编码。如果不正确,验证过程将失败,导致"signatureValue错误"。本文将深入探讨如何解决此问题,提供详细的分步指导和示例代码。

问题:错误的 base64 编码

在 Python 中生成 ZATCA 电子发票 XML 时,许多开发人员发现很难获得正确的 base64 编码数字证书。这导致签名验证失败,并显示"signatureValue错误"。

解决方法

1. 使用 ElementTree 进行 XML 处理

使用 ElementTree(ET)库处理 XML,而不是 lxml 或其他库。ET 提供了符合 ZATCA 规范的正确规范化功能。

2. 规范化 XML

使用 Chilkat 的 CanonicalizeXml 函数对 XML 进行规范化,确保以标准方式排列元素和属性。

3. 使用 SHA-256 哈希算法

对规范化的 XML 使用 SHA-256 哈希算法进行哈希处理,生成哈希摘要。

4. 正确编码签名

使用 OpenSSL 对哈希进行签名,然后使用 base64 对签名进行编码。确保使用正确的命令行选项。

示例代码

以下经过修改的代码演示了如何实施这些修复:

import ElementTree as ET
import chilkat2
import sha256
import base64
import os

# ... (其他代码)

# 对 XML 进行规范化
xmldsig = chilkat2.XmlDSig()
canonXml = xmldsig.CanonicalizeXml(new_xml.decode(), "C14N", False)

# 对规范化的 XML 进行哈希处理
invoice_hash_digest = sha256(canonXml.encode()).digest()

# 将哈希编码为 base64
invoice_hash_digest_b64_encoded = base64.b64encode(invoice_hash_digest) 

# ... (其他代码)

# 使用 OpenSSL 对哈希进行签名并编码为 base64
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).decode("utf-8")

结论

通过遵循本文的步骤,您应该能够解决 ZATCA 电子发票数字证书 base64 编码问题。规范化 XML、使用正确的哈希算法并正确编码签名将确保生成符合规范的 XML。

常见问题解答

1. 为什么使用 ElementTree?

ElementTree 符合 ZATCA 规范,提供正确的 XML 规范化,而 lxml 等其他库可能不会。

2. Chilkat 的 CanonicalizeXml 函数有什么作用?

它将 XML 标准化为 C14N 格式,以便在验证过程中对其进行一致处理。

3. 使用 SHA-256 哈希算法有什么好处?

SHA-256 是 ZATCA 规范中指定的算法,用于生成哈希摘要。

4. 为什么使用 OpenSSL 对哈希进行签名?

OpenSSL 是一个久经考验的工具,可用于对哈希进行签名。

5. base64 编码如何帮助?

它将二进制签名转换为文本字符串,便于传输和存储。