我正在编写一个python脚本来验证新西兰的疫苗接种护照。在我有政府证书和已解码的COSE信息时,我很挣扎,我需要努力验证它的签名:
key_as_dict = {
KpKty: cose.keys.keytype.KtyEC2,
# OKPKpCurve: cose.keys.curves.EllipticCurve, # this one also does not work
OKPKpCurve: cose.keys.keytype.KtyEC2,
OKPKey: kid,
KpKeyOps: [VerifyOp],
OKPKpD: jwk_key['x'],
OKPKpX:jwk_key['y'],
}
govt_key = CoseKey.from_dict(key_as_dict)
cose_decoded.key = govt_key
print("key ready")
print("header", cose_decoded.verify_signature())错误消息:
cose.exceptions.CoseInvalidKey: COSE curve cannot be None这是政府为测试目的提供的JWK密钥:
{
"kty": "EC",
"crv": "P-256",
"x": "zRR-XGsCp12Vvbgui4DD6O6cqmhfPuXMhi1OxPl8760",
"y": "Iv5SU6FuW-TRYh5_GOrJlcV_gpF_GpFQhCOD8LSk3T0"
}有人知道如何正确地将政府证书映射到关键字典吗?
更多信息:
发布于 2021-12-14 22:26:39
它失败的原因是您对给定的密钥使用了错误的键型。
对于作为JWK ("kty": "EC")提供的密钥,您需要使用EC2,但是在代码中,您试图将其映射到OKP参数。
因此,首先需要更改代码导入部分中的两行:
#from cose.keys.keyparam import KpKty, OKPKpCurve, OKPKpD, OKPKpX
from cose.keys.keyparam import KpKty, EC2KpCurve, EC2KpX, EC2KpY
#from cose.keys.okp import OKPKey
from cose.keys.ec2 import EC2Key然后从JWK中提取关键参数x和y。这些参数存储在Base64Url编码中,需要解码。Python Base64解码器坚持使用填充,尽管Base64Url不需要它。因此,在解码前要在Base64Url编码的字符串上添加填充"=“的神秘代码:
x = jwk_key['x']
if len(x) % 4:
x = x + "=" * (4 - len(x)%4)
ec_x = base64.urlsafe_b64decode(x)
y = jwk_key['y']
if len(y) % 4:
y = y + "=" * (4 - len(y)%4)
ec_y = base64.urlsafe_b64decode(y)最后,将映射代码更改如下:
key_as_dict = {
KpKty: cose.keys.keytype.KtyEC2,
EC2KpCurve: P256,
EC2Key: kid,
KpKeyOps: [VerifyOp],
EC2KpX: ec_x,
EC2KpY: ec_y,
}如您所见,我将参数从OKP...更改为EC2...对应方
程序的输出(我跳过了第1..5部分,正如您已经知道的结果)是:
*第6部分:核证证明书 钥匙准备好 报头真
下面是一个最小的可运行示例,它只显示了基于代码中一个硬编码的JWK键的键映射:
import base64
import cose
from cose.keys.curves import P256, CoseCurve
from cose.keys.keyparam import KpKty, EC2KpCurve, EC2KpX, EC2KpY
from cose.keys.keyparam import KpKeyOps
from cose.keys.keyops import SignOp, VerifyOp
from cose.keys import CoseKey
from cose.keys.ec2 import EC2Key
import json
# this is in reality loaded from the web
jwk_string = '''{"kty": "EC", "crv": "P-256",
"x": "zRR-XGsCp12Vvbgui4DD6O6cqmhfPuXMhi1OxPl8760",
"y": "Iv5SU6FuW-TRYh5_GOrJlcV_gpF_GpFQhCOD8LSk3T0"}'''
jwk_key = json.loads(jwk_string)
kid = "123" # just an example
# mapping the incoming JWK to a COSE key
x = jwk_key['x']
if len(x) % 4:
x = x + "=" * (4 - len(x)%4)
ec_x = base64.urlsafe_b64decode(x)
y = jwk_key['y']
if len(y) % 4:
y = y + "=" * (4 - len(y)%4)
ec_y = base64.urlsafe_b64decode(y)
key_as_dict = {
KpKty: cose.keys.keytype.KtyEC2,
EC2KpCurve: P256,
EC2Key: kid,
KpKeyOps: [VerifyOp],
EC2KpX: ec_x,
EC2KpY: ec_y,
}
govt_key = CoseKey.from_dict(key_as_dict)
print("key ready")附带说明:确保ECDSA包是最新的。我的PC上已经有了一个旧版本,在验证过程中出现了一个奇怪的错误:
TypeError: from_public_point()得到了一个意外的关键字参数'validate_point‘
在升级后消失了:
pip install ecdsa --upgradehttps://stackoverflow.com/questions/70192701
复制相似问题