首页 > 解决方案 > 使用 openSSL 验证 EU GreenPass

问题描述

我刚收到我的 Covid Green Pass。我已经开始对其进行解码,这是我得到的字段:

header: a20448349a42b0c2d0728e0126
payload: a4041a645d8180061a61053b9501624954390103a101a4617681aa62646e01626d616d4f52472d3130303033313138346276706a313131393334393030376264746a323032312d30372d313462636f624954626369782630314954303544314444
signature: 6f422bd436e216177de025d3d31681a27bead6115f480630754db6f1498bbc782cdc975f4c4d79af77dbe02c31de6af4ba94d7fe11510a5ca6121cb0bf10890a

在此示例中,所有字段都是十六进制。有效载荷是一个 CBOR 结构,可以进一步解码以获取您的数据。

验证 GreenPass

我现在想做的是使用 Unix 工具验证签名openssl。我发现绿色通道签名是使用椭圆曲线数字签名算法 (ECDSA) 创建的,使用 P-256 参数和 SHA-256 哈希算法。

有了openssl,我应该能够验证这个绿卡:

$ openssl dgst -sha256 -verify public_key_it -signature my_signature my_data

我需要三个参数public_key_itmy_signaturemy_data

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEnL9+WnIp9fvbcocZSGUFlSw9ffW/jbMONzcvm1X4c+pXOPEs7C4/83+PxS8Swea2hgm/tKt4PI0z8wgnIehojw==
-----END PUBLIC KEY-----
echo "6f422bd436e216177de025d3d31681a27bead6115f480630754db6f1498bbc782cdc975f4c4d79af77dbe02c31de6af4ba94d7fe11510a5ca6121cb0bf10890a" | xxd -r -p > my_signature
jSignature1MH4Br&@Y7d]a;bIT9avbdnbmamORG-100031184bvpj1119349007bdtj2021-07-14bcobITbcix&01IT05D1DDD951474B1C93D161A4F4663B8E#3bmplEU/1/20/1507bisvMinistero della Salutebsdbtgi840539006cnamcfntfDUPONTbfnfDUPONTcgntxCORENTIN<NICOLAS<MARIE<FRANCOISbgnx"CORENTIN, NICOLAS, MARIE, FRANCOIScvere1.0.0cdobj1978-11-17

有些字符是不可打印的,所以这里又是十六进制:

846a5369676e6174757265314da20448349a42b0c2d0728e012640590137a4041a645d8180061a61053b9501624954390103a101a4617681aa62646e01626d616d4f52472d3130303033313138346276706a313131393334393030376264746a323032312d30372d313462636f62495462636978263031495430354431444444393531343734423143393344313631413446343636334238452333626d706c45552f312f32302f31353037626973764d696e69737465726f2064656c6c612053616c7574656273640162746769383430353339303036636e616da463666e74664455504f4e5462666e664455504f4e5463676e74781f434f52454e54494e3c4e49434f4c41533c4d415249453c4652414e434f495362676e7822434f52454e54494e2c204e49434f4c41532c204d415249452c204652414e434f49536376657265312e302e3063646f626a313937382d31312d3137

好吧,如果我尝试上面的 openssl 命令,我会得到:

$ openssl dgst -sha256 -verify public_key_it -signature my_signature my_data
Error Verifying Data
140529059103168:error:0D07209B:asn1 encoding routines:ASN1_get_object:too long:../crypto/asn1/asn1_lib.c:91:
140529059103168:error:0D068066:asn1 encoding routines:asn1_check_tlen:bad object header:../crypto/asn1/tasn_dec.c:1137:
140529059103168:error:0D07803A:asn1 encoding routines:asn1_item_embed_d2i:nested asn1 error:../crypto/asn1/tasn_dec.c:309:Type=ECDSA_SIG

有什么提示吗?我什至走在正确的轨道上吗?谢谢

编辑:我现在解决了这个问题。我在一篇博文中写了所有细节:http: //www.corentindupont.info/blog/posts/Programming/2021-08-13-GreenPass.html

标签: unixopensslqr-codesha256cbor

解决方案


在@MichaelFehr 的帮助下,我设法解决了这个问题!

签名转换

GreenPass 具有“原始”(P1363) 格式的签名。但是,openssl只接受 DER 格式。所以我们需要转换它。

这是我的签名:

6f422bd436e216177de025d3d31681a27bead6115f480630754db6f1498bbc782cdc975f4c4d79af77dbe02c31de6af4ba94d7fe11510a5ca6121cb0bf10890a

它有 64 个字节长。它由两个整数 R 和 S 组成。R 是前半部分,而 S 是后半部分。

R = 6f422bd436e216177de025d3d31681a27bead6115f480630754db6f1498bbc78
S = 2cdc975f4c4d79af77dbe02c31de6af4ba94d7fe11510a5ca6121cb0bf10890a

根据DER编码,我需要添加更多字节:

30  -- fixed value for composed structure
44  -- size of everything that follows
02  -- fixed value for integer
20  -- size of the R integer
6f422bd436e216177de025d3d31681a27bead6115f480630754db6f1498bbc78  -- R
02  -- fixed value for integer
20  -- size of the S integer
2cdc975f4c4d79af77dbe02c31de6af4ba94d7fe11510a5ca6121cb0bf10890a  -- S

如果我组装它,我可以获得我的 DER 签名:

echo -n "304402206f422bd436e216177de025d3d31681a27bead6115f480630754db6f1498bbc7802202cdc975f4c4d79af77dbe02c31de6af4ba94d7fe11510a5ca6121cb0bf10890a" | xxd -r -p > my_signature.der

数据转换

数据部分也需要组合。根据COSE 规范,我需要从绿卡数据中构建一个“Sig_structure”。此 Sig_structure 用于创建签名和验证签名。

这是完成的“Sig_structure”:

846a5369676e6174757265314d  -- "Signature1" in hexadecimals
a20448349a42b0c2d0728e0126  -- My header (see original post above)
40590137                    -- some separator... not sure
a4041a645d8180061a61053b9501624954390103a101a4617681aa62646e01626d616d4f52472d3130303033313138346276706a313131393334393030376264746a323032312d30372d313462636f62495462636978263031495430354431444444393531343734423143393344313631413446343636334238452333626d706c45552f312f32302f31353037626973764d696e69737465726f2064656c6c612053616c7574656273640162746769383430353339303036636e616da463666e74664455504f4e5462666e664455504f4e5463676e74781f434f52454e54494e3c4e49434f4c41533c4d415249453c4652414e434f495362676e7822434f52454e54494e2c204e49434f4c41532c204d415249452c204652414e434f49536376657265312e302e3063646f626a313937382d31312d3137 -- my payload (see above)

我们现在可以创建my_data

echo -n "846a536967..." | xxd -r -p > my_data.bin

它现在有效!

$ openssl dgst -sha256 -verify public_key_it -signature my_signature.der my_data
Verified OK

推荐阅读