You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何反向改造荷兰新冠证书Base45解码Python代码实现编码功能

荷兰NL2格式新冠证书编码工具实现

前置依赖

你需要先安装以下Python依赖包:

  • pyasn1、pyasn1-modules:用于ASN.1格式数据的序列化与校验
  • base45:用于Base45标准编解码
    安装命令:pip install pyasn1 pyasn1-modules base45

编码逻辑说明

对应原解码流程的逆向步骤如下:

  1. 按照荷兰官方NL2证书的ASN.1结构定义,构造对应的ASN对象模板
  2. 将输入的结构化参数(证书版本、公钥校验值、isSpecimen标识、validFrom生效时间、有效期、个人信息等)填入模板对应字段
  3. 序列化ASN对象得到二进制原始数据
  4. 对二进制数据进行Base45编码
  5. 拼接NL2:前缀,得到最终可生成二维码的编码字符串

完整实现代码

from pyasn1.type import univ, char, namedtype, useful
from pyasn1.codec.der.encoder import encode as der_encode
import base45
from datetime import datetime

# 对应NL2证书的ASN.1结构定义,需和原解码逻辑完全匹配
class NL2Certificate(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.NamedType('version', univ.Integer()),
        namedtype.NamedType('keyIdentifier', univ.OctetString()),
        namedtype.NamedType('isSpecimen', univ.Boolean()),
        namedtype.NamedType('validFrom', useful.GeneralizedTime()),
        namedtype.NamedType('validTo', useful.GeneralizedTime()),
        # 可根据原解码得到的其他字段继续扩展,比如接种/检测记录字段等
        namedtype.OptionalNamedType('firstName', char.UTF8String()),
        namedtype.OptionalNamedType('lastName', char.UTF8String()),
        namedtype.OptionalNamedType('birthDate', char.UTF8String()),
        namedtype.OptionalNamedType('credentialType', univ.Integer())
    )

def generate_nl2_cert(cert_params: dict) -> str:
    """
    输入结构化证书参数,生成NL2格式Base45编码字符串
    :param cert_params: 参数字典,需包含version、keyIdentifier、isSpecimen、validFrom、validTo必填字段
                        可选填入firstName、lastName、birthDate、credentialType等扩展字段
    :return: 带NL2:前缀的Base45编码字符串
    """
    # 初始化ASN证书对象
    cert = NL2Certificate()
    
    # 填充必填字段
    cert['version'] = cert_params['version']
    cert['keyIdentifier'] = univ.OctetString.fromHexString(cert_params['keyIdentifier'])
    cert['isSpecimen'] = cert_params['isSpecimen']
    
    # 转换时间格式为ASN.1标准GeneralizedTime格式
    def time_to_asn_format(dt: datetime) -> useful.GeneralizedTime:
        return useful.GeneralizedTime(dt.strftime("%Y%m%d%H%M%SZ"))
    
    cert['validFrom'] = time_to_asn_format(cert_params['validFrom'])
    cert['validTo'] = time_to_asn_format(cert_params['validTo'])
    
    # 填充可选字段
    optional_fields = ['firstName', 'lastName', 'birthDate', 'credentialType']
    for field in optional_fields:
        if field in cert_params:
            cert[field] = cert_params[field]
    
    # DER序列化ASN对象为二进制
    der_binary = der_encode(cert)
    
    # Base45编码二进制数据
    base45_str = base45.b45encode(der_binary).decode('ascii')
    
    # 拼接NL2前缀返回
    return f"NL2:{base45_str}"

使用示例

if __name__ == "__main__":
    # 示例参数,可根据实际需求替换字段值、新增自定义字段
    test_params = {
        "version": 1,
        "keyIdentifier": "A1B2C3D4E5F67890", # 公钥标识的十六进制字符串
        "isSpecimen": False,
        "validFrom": datetime(2023, 1, 1, 0, 0, 0),
        "validTo": datetime(2023, 12, 31, 23, 59, 59),
        "firstName": "张三",
        "lastName": "李",
        "birthDate": "1990-01-01",
        "credentialType": 2 # 1=接种证明 2=检测证明 3=康复证明,可根据官方规范调整
    }
    
    final_code = generate_nl2_cert(test_params)
    print("生成的NL2编码字符串:", final_code)

注意事项

  • 若你现有解码代码中的ASN.1结构和上述定义不一致,需根据解码时的字段顺序、类型调整NL2Certificate类的componentType定义,结构完全匹配才能生成可正常解码的证书
  • keyIdentifier字段值需和签名用私钥对应的公钥哈希值一致,否则解码时公钥校验会失败
  • 本实现仅生成符合格式要求的编码字符串,如需可视化二维码,可配合qrcode等二维码生成库使用

内容的提问来源于stack exchange,提问作者MitchGamesNL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 04:45:05