首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从JWK密钥创建密钥,以便使用Python验证COSE签名-1?

如何从JWK密钥创建密钥,以便使用Python验证COSE签名-1?
EN

Stack Overflow用户
提问于 2021-12-01 23:54:38
回答 1查看 304关注 0票数 1

我正在编写一个python脚本来验证新西兰的疫苗接种护照。在我有政府证书和已解码的COSE信息时,我很挣扎,我需要努力验证它的签名:

代码语言:javascript
复制
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())

错误消息:

代码语言:javascript
复制
cose.exceptions.CoseInvalidKey: COSE curve cannot be None

这是政府为测试目的提供的JWK密钥:

代码语言:javascript
复制
{
  "kty": "EC",
  "crv": "P-256",
  "x": "zRR-XGsCp12Vvbgui4DD6O6cqmhfPuXMhi1OxPl8760",
  "y": "Iv5SU6FuW-TRYh5_GOrJlcV_gpF_GpFQhCOD8LSk3T0"
}

有人知道如何正确地将政府证书映射到关键字典吗?

更多信息:

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-14 22:26:39

它失败的原因是您对给定的密钥使用了错误的键型

对于作为JWK ("kty": "EC")提供的密钥,您需要使用EC2,但是在代码中,您试图将其映射到OKP参数。

因此,首先需要更改代码导入部分中的两行:

代码语言:javascript
复制
#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编码的字符串上添加填充"=“的神秘代码:

代码语言:javascript
复制
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)

最后,将映射代码更改如下:

代码语言:javascript
复制
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键的键映射:

代码语言:javascript
复制
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‘

在升级后消失了:

代码语言:javascript
复制
pip install ecdsa --upgrade
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70192701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档