生成具有预定义模数和指数的公钥

Posted

技术标签:

【中文标题】生成具有预定义模数和指数的公钥【英文标题】:Generate a public key with a predefined modulus and exponent 【发布时间】:2021-05-01 08:09:16 【问题描述】:
"n": "rKZ-1zdz_CoLekSynOtyWv6cPSSkV28Kb9kZZHyYL-yhkKnH_bHl8OpWiGxQiKP0ulLRIaq1IhSMetkZ8FfXH-iptIDu4lPb8gt0HQYkjcy3HoaKRXBw2F8fJQO4jQ-ufR4l-E0HRqwLywzdtAImNWmju3A4kx8s0iSGHGSHyE4EUdh5WKt-NMtfUPfB5v9_2bC-w6wH7zAEsI5nscMXnvz1u8w7g2_agyhKSK0D9OkJ02w3I4xLMlrtKEv2naoBGerWckKcQ1kBYUh6WASPdvTqX4pcAJi7Tg6jwQXIP1aEq0JU8C0zE3d33kaMoCN3SenIxpRczRzUHpbZ-gk5PQ",
"e": "AQAB",

如何从这些值生成公钥?最好通过 python 或 Linux 程序。如果由于值无效,问题是无稽之谈,我很抱歉。

来源是here。

【问题讨论】:

【参考方案1】:

在 Python 中,您可以使用 Python-JOSE

您的链接中有一个 JSON Web Key Set (JWKS),一个 JSON 格式的 JSON Web Keys (JWK) 数组。

ne 是公共 RSA 密钥的模数和指数。

jwk.construct 函数可以直接从 JWK 创建密钥。然后可以使用密钥,例如验证 JWT (key.verify)。

您也可以使用jwt.decode,如下面的代码所示,并直接传递 JWK,或以 PEM 格式传递。

from jose import jwk
from jose.utils import base64url_decode

token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlctNjduZWt0WVRjOEpWWVBlV0g1c1dlN1JZVm5uMFN5NzQxZjhUT0pfQWMifQ.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.hiKxeC66LIyVKOXjiOk7iScFPy_5-ATw7hEfqGij8sBZmwXAeTPT5BRFYHitFKSXomGqmy_63LLvg4zbhcTTmNf8XIeDAuLsC32soO5woSByisswWHVf8BgxMkI_FPW_oEtEQ8Xv3FL_1rF9j9Oy3jIjgjqhFhXUtsSQWAeuGYH-OQljFwiuO5Bqexcw-H71OEWvQLQof_6KJ0viJyte8QEwEVridyO834-ppHzeaoW2sTvZ22ZNfxPCew0Ul2V_TxHTtO7ZuJCZ81EmeIV6dYJ2GrYh3UN1x1PHy4-tEn-PL4otlaO3PYOcXfCHxHa6xtPsquzPZJnB1Vq8zULLfQ"

rsa_key = 
    "kty": "RSA",
    "kid": "W-67nektYTc8JVYPeWH5sWe7RYVnn0Sy741f8TOJ_Ac",
    "use": "sig",
    "alg": "RS256",
    "n": "kFpGoVmBmmKepvBQiwq3hU9lIAuGsAPda4AVk712d3Z_QoS-5veGp4yltnyEFYyX867GOKDpbH7OF2uIjDg4-FPZwbuhiMscbkZzh25SQmfRtCT5ocUloQiopBcNAE-sd1p-ayUJWjhPrFoBrBLZHYxVEjY4JrWevQDj7kSeX7eJpud_VuZ77TNoIzj7d_iUuJUUlqF1ZF540igHKoVJJ6ujQLHh4ob8_izUuxX2iDq4h0VN3-uer59GsWw6OHgkOt85TsjMwYbeN9iw_7cNfLEYpSiH-sVHBCyKYQw7f8bKaChLxDRhUUTIEUUjGT9Ub_A3gOXq9TIi8BmbzrzVKQ",
    "e": "AQAB"


key = jwk.construct(rsa_key)

message, encoded_sig = token.rsplit('.', 1)
decoded_sig = base64url_decode(encoded_sig + '=' * (4 - len(encoded_sig) % 4)) # looks weird, but without added padding I got errors
res = key.verify(bytes(message, "UTF-8"), decoded_sig)
# jwt.decode(token=token, key=key.to_pem().decode(), algorithms= 'RS256') # with PEM key
payload = jwt.decode(token=token, rsa_key, algorithms= 'RS256') # with JWK
print(res)
print(payload)

结果是

是的 'sub': '1234567890', 'name': 'John Doe', 'admin': True, 'iat': 1516239022

这意味着可以使用该密钥验证令牌。

【讨论】:

谢谢!你能解释一下为什么右键(key.to_pem())返回TypeError: a bytes-like object is required, not 'str'from jose import jwt令牌:***.com/q/65909233/14190526(太长,无法进入评论)jwt.decode(token=text, key=key.to_pem(), algorithms=algorithms) 查看我编辑的答案:key=key.to_pem().decode() 错误消失了。 是的,但出现另一个错误:jose.exceptions.JWTClaimsError: Invalid audience。我有观众的凭据,但不知道如何通过它 你可以像这样设置一个参数:audience = allowed_aud,。另见***.com/questions/62822313/… 刚才我检查了它并且它正在工作,由于某种原因它还需要access_token,但我在凭据中有它。有些人(比如我)不会为他们自己的问题投票,因为他们不是专家,这可能会导致混乱,因为其他人会认为这个问题得到了专家的支持。现在我的问题完全解决了,谢谢。顺便说一句,您知道将公钥存储在本地还是在线查看更可取吗?如果在本地:这些密钥是等效的,还是每次都会用另一个密钥签名,因此我需要迭代以获取当前密钥?

以上是关于生成具有预定义模数和指数的公钥的主要内容,如果未能解决你的问题,请参考以下文章

从模数和指数生成 RSA 公钥

在 Objective-c 中从模数和指数以字节为单位生成 RSA 公钥

如何验证 Apple 登录的 Jwt 令牌(后端验证)。如何从 Java 中的模数和指数 (n,e) 生成 RSA 公钥

.net 中 RSA 公钥模数和指数的格式是啥?

RSA:在给定公钥的情况下获取指数和模数

使用Python从公钥获取RSA指数和模数