如何使用OpenSSL验证欧盟EU GreenPass新冠绿色通行证的签名
验证思路正确性
你的整体验证思路是符合规范的:已经完成了HCERT解码提取CBOR字段、按照RFC8152构造Sig_structure待签名数据、获取对应区域公钥的全部前置步骤,核心逻辑匹配欧盟数字新冠证书的签名验证标准流程。
问题核心原因
返回的错误日志已经明确指向问题根源:ECDSA_SIG类型的ASN.1解码失败,差异点在于签名格式不匹配:
- 欧盟绿色通行证遵循的COSE规范中,P-256 ECDSA签名采用原始拼接格式:直接拼接32字节r值 + 32字节s值,你当前导出的
my_signature就是该格式 openssl dgst命令默认要求ECDSA签名为ASN.1 DER编码格式,无法直接解析raw拼接格式的签名,因此抛出解码错误
解决方法
有两种可直接落地的修复方案:
方案1:将raw签名转换为DER格式后验证
按照ECDSA DER编码规则,将你现有的签名拼接为符合openssl要求的格式:
你的签名十六进制为:6f422bd436e216177de025d3d31681a27bead6115f480630754db6f1498bbc782cdc975f4c4d79af77dbe02c31de6af4ba94d7fe11510a5ca6121cb0bf10890a
拆分后前32字节(64个十六进制字符)为r值,后32字节为s值,拼接为DER格式的十六进制为:304402206f422bd436e216177de025d3d31681a27bead6115f480630754db6f1498bbc7802202cdc975f4c4d79af77dbe02c31de6af4ba94d7fe11510a5ca6121cb0bf10890a
执行命令生成DER格式签名文件:
echo -n "304402206f422bd436e216177de025d3d31681a27bead6115f480630754db6f1498bbc7802202cdc975f4c4d79af77dbe02c31de6af4ba94d7fe11510a5ca6121cb0bf10890a" | xxd -r -p > my_signature.der
再执行验证命令即可:
openssl dgst -sha256 -verify public_key_it -signature my_signature.der my_data
方案2:使用openssl pkeyutl直接验证raw格式签名
不需要转换签名格式,直接用支持raw签名验证的pkeyutl子命令执行验证:
openssl pkeyutl -verify -pubin -inkey public_key_it -rawin -digest sha256 -in my_data -sigfile my_signature
额外注意项
请确保你构造的my_data文件是十六进制内容通过xxd -r -p导出的二进制文件,而非直接保存的十六进制文本,否则也会导致验证失败。
内容的提问来源于stack exchange,提问作者cdupont

