如何从 RSA 密钥对创建 JWK?

问题描述 投票:0回答:2

假设我有一个代表 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 代码来做到这一点。

python jwt rsa jwk
2个回答
9
投票

以下是如何使用 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"
}

通过 http://docs.authlib.org/en/latest/jose/jwk.html


0
投票

您可以使用以下代码生成 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))
© www.soinside.com 2019 - 2024. All rights reserved.