假设我有一个代表 RSA 密钥对的 python 结构,如下所示:
rsa_key_pair = {
'private_key': '-----BEGIN PRIVATE KEY-----\nMIIEvAIBADAN__OBSCURED__qxu3sWAlY/bstTB5WfX8PA==\n-----END PRIVATE KEY-----\n',
'public_key': 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCDDqGTiBYyoB9T5Haow5gcPBIIiltLVyM4vo8Txia1czgrk2XGH5t4dsWrcXIXjQafNb7PKelXZdRU36vIIAaZCZ0As5LtkC5D93+KO9PFLGkHxWi2G43naR9hOnrKliMjOd+JRUdApdY8c/wYJbDxGGuw7W9e3MsLABFEK+TnPTVJtO8Ix78FiuHRooWfU5ph7clfTeyundN2BNv8mO6ZSBiBAk6tN8Fwpljs96Z/3HnMQutX1/AFkMn5h+E0EV4CgLPvtRazfzoWNlIiXGmiVUVHrM1wna9jT/jyb7aoxkthkAXb6NNyCW/Znxq45Ozy27kZcw/X4WQ0QMmpgfX'
}
如何编写 python 代码来生成可用于验证使用此 RSA 私钥签名的 JWT 的 JWK?使用的算法是RSA256。
这个网站mkjwk完成了我想做的事情。但我正在尝试用 python 代码来做到这一点。
以下是如何使用 Authlib 转储 JWK 的示例:
from authlib.jose import jwk
jwk.dumps(rsa_key_pair['public_key'], kty='RSA')
jwk.dumps(rsa_key_pair['private_key'], kty='RSA')
这是您的公钥的结果:
{
"kty": "RSA",
"n": "wgw6hk4gWMqAfU-R2qMOYHDwSCIpbS1cjOL6PE8YmtXM4K5Nlxh-beHbFq3FyF40GnzW-zynpV2XUVN-ryCAGmQmdALOS7ZAuQ_d_ijvTxSxpB8VothuN52kfYTp6ypYjIznfiUVHQKXWPHP8GCWw8RhrsO1vXtzLCwARRCvk5z01SbTvCMe_BYrh0aKFn1OaYe3JX03srp3TdgTb_JjumUgYgQJOrTfBcKZY7Pemf9x5zELrV9fwBZDJ-YfhNBFeAoCz77UWs386FjZSIlxpolVFR6zNcJ2vY0_48m-2qMZLYZAF2-jTcglv2Z8auOTs8tu5GXMP1-FkNEDJqYH1w",
"e": "AQAB"
}
您可以使用以下代码生成 JWKS,其中包括有关证书的信息(例如 x5t、x5c)。 由于证书中已经包含了公钥的信息,所以不需要单独传递公钥。
要了解有关如何为 JWT 生成数字签名 RSA 对的更多信息,请参阅此处
import base64
import json
from cryptography.hazmat.primitives.hashes import SHA1
from jose import constants, jwk
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
class JWKSGenerator:
def __init__(
self,
*,
file_path: str,
kid: str,
use: str = 'sig',
) -> None:
with open(file_path, 'rb') as f:
self._cert_pem_raw_data: bytes = f.read().strip()
self._cert = x509.load_pem_x509_certificate(self._cert_pem_raw_data, default_backend())
self._kid = kid
self._use = use
def _create_x5t(self, ):
digest = self._cert.fingerprint(algorithm=SHA1())
return base64.b64encode(digest).decode('utf-8')
def _create_x5c(self, ):
cert_val = self._cert.public_bytes(serialization.Encoding.DER)
return base64.b64encode(cert_val).decode('utf-8')
def process(self):
jwks = jwk.RSAKey(algorithm=constants.Algorithms.RS256, key=self._cert_pem_raw_data).to_dict()
jwks.update({
"x5t": self._create_x5t(),
"x5c": [
self._create_x5c()
],
"kid": self._kid,
"use": self._use,
})
print(json.dumps(jwks, indent=4))
return jwks
JWKSGenerator(
file_path='<complete path to certificate pem file>',
kid="key_id_123",
).process()
如果您没有证书,可以使用以下代码:
jwks = jwk.RSAKey(algorithm=constants.Algorithms.RS256, key=open('<path_to_public_key>'>, 'rb')).to_dict()
jwks.update({
"kid": '<key_id>',
"use": 'sig',
})
print(json.dumps(jwks, indent=4))