stu*_*ent 3 python cryptography rsa jwt pyjwt
我正在尝试转换此 java 代码以在 python 中生成 JWT 令牌。
String privateKeyContent = privateKey
.replaceAll(Definitions.ApiGeneral.LINE_BREAKER, "")
.replace(Definitions.AuthProperty.PRIVATE_KEY_START, "")
.replace(Definitions.AuthProperty.PRIVATE_KEY_END, "");
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));
KeyFactory kf = KeyFactory.getInstance(Definitions.AuthProperty.RSA_KEY_FACTORY);
PrivateKey privKey = kf.generatePrivate(keySpecPKCS8);
String jwtAudUrl = System.getenv(Definitions.IamProperty.IAM_URL_KEY) + System.getenv(Definitions.IamProperty.JWT_AUD_URI_KEY);
String jwtToken = Jwts.builder()
.setAudience(jwtAudUrl)
.setSubject(serviceId)
.setIssuer(serviceId)
.setExpiration(new Date(new Date().getTime() + TimeUnit.MINUTES.toMillis(Definitions.AuthProperty.JWT_TOKEN_EXPIRY_IN_MINUTES)))
.signWith(privKey)
.compact();
Run Code Online (Sandbox Code Playgroud)
Python:
import jwt
serviceID = "abc"
secret = '-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCAQEAhstYtRbkgQkFwlVr8QjSCQqqRTDMKWHdIGRYBpXcQmvKfagId9nBA2Ygh7cOrT9g8MhxYo8U1jYmPQpv6gf3LgO/J0qspLdaAhZP6LusA/HHJBR7kjTXBsLcsEDyd8S0UioBYP3DLvtWhGIR2f4o7SH1TlE96tldV6FZKGO2NHsJrJwTd+ym0AeZe0b7QZLe43LBCTLdqk05U34jrknJliSAEbGqYg4h6nrJsKBC/0pmiQ9ptD1N/Kl4bqffMWIbZq2bPP6jFrmBLe+7yTeVMKltVbJZys4nHhyYngBtbAxynXeB2tpE8If7cK75fj42MlFgquEiEZZVSzNNmrmPOwIDAQABAoH/B18Xes/Fr0jPB9GkFYpl8hijNyV0BM9VSHA0YCfR49ABQt3tmKBP7d+n58QbCV5t7r0Hdlxcx1ouvSfU9vd4jQunaH6s8lUUlwihVhjtT0npmg+EsnoxSC1f5EOo/uPC+LtTV/qIsgkMsjCqyUEc+9rfj2jh+fXpJOGt/od1b2k2xs84MsXmSF/As7GYRdw+FLbkN64R/SGmv3NLtQdg5uvBKLuKvtQWIJBuPqgKOsJWaCVO0XaoUDQeav/nTfP0ntmF0QH9JtXYzBldhGq2FPVQRUaCuJ4YPEpXlD3FptQBlX/Wu7wXbdwDz3qyXbGqSkiaR3gN+QR+IgjG3oQxAoGBAML5M4Dg0S/yobHuCRcvpngraXGBWnCTaD0mMh/cosV0HBNdZbglwVpG8Agz9BEYIrDM777HFuB+lWUvGNMR45rObPcDqn7Qj8Uwnj775Bg0Sx09MCBds6IGce/92uPUsHPx4pj8dzCj1s3cfUKO+EaUE33bnFXcMCGh/0x0sIVXAoGBALD8H4Aph2OPQK9OOHb3ULDvrmMPrpe3xv5iSzfLt7xBIP2G0Wl+q0hzEtdEOUZGQemOtyuV5t9Jwwfh9uH9jAhk9OEvoNg3F3mQl6hjmHPd1xUNvRTqwnV+VvQnw7Aeq2TZMcAKwbXf3+p430wMsxR6m0Y7rGi0FIxWbILp0RK9AoGBAIfiPBXnGYOsOysRtb42FHQN9WgI+eoZof10IFz6XWr12Bda8Wicz5vGcsWUx9YeFxdXTQOOJ5CASEiDwW5hOlqK4YBqSqolWv3YO4Gz9i00TOFs4py8EVSr3z6ekq5UbkHwY7exxLPei/dfYuE/WSN/UfJWWyev1M+r4oz7iobzAoGAKe8S56LvWT+P6/l0l3txuvqPLxmAHKKGm69ecxHprskfr/JJm91PaBMb27VmfKgY5eXSsJkL4svvUebQQCt7CmIhQ1mtmo0zGrKPvG4cqRde5rYintogyQXuRFtHmmsp4PM1PnNOAnHQ9BU/kx1PMQL712A8MXK5i6bOfxY3W2ECgYEAp9cw3NeMSy/WcXyZoyNFUdEQiHTJGPBtELjHWRnjMU1454EkWYYPiYXUnElfxP6InxHgMNbGVsd1BUEhXOdSUS5bO/WBOOPqSh6MIGfKFuMN/9SI/Y/UZKltCD1CboTvDfmkD+opkLM6YZpW9CRT7Szn7ivdFr5KqGQZUZOwn3k=-----END RSA PRIVATE KEY-----'
due_date = datetime.now() + timedelta(minutes=10)
header = {"alg": "RS256"}
expiry = int(due_date.timestamp())
payload = {"iss": serviceID, "sub": serviceID, "exp": expiry, "aud": iam_url + "/oauth2/access_token"}
priv_rsakey = serialization.load_pem_private_key(secret.encode('utf8'), password=None, backend=default_backend())
token=jwt.encode(payload, priv_rsakey, algorithm='RS256')
Run Code Online (Sandbox Code Playgroud)
但是,我不断收到此错误:
ValueError: ('Could not deserialize key data. The data may be in an incorrect format, it may be encrypted with an unsupported algorithm, or it may be an unsupported key type (e.g. EC curves with explicit parameters).', [_OpenSSLErrorWithText(code=503841036, lib=60, reason=524556, reason_text=b'error:1E08010C:DECODER routines::unsupported')])
Run Code Online (Sandbox Code Playgroud)
有人可以帮我解决这个问题吗?
错误消息中准确识别了该问题:您的私钥格式不正确。PEM 编码密钥由 Base64 编码主体组成,其中每 64 个字符后包含一个换行符,以及单独行上的页眉和页脚。您的密钥缺少换行符。
load_pem_private_key()至少期望页眉和页脚位于单独的行上,但可以容忍正文中的换行符,即它们是可选的。所以你必须传递你的密钥,例如这样:
secret = '-----BEGIN RSA PRIVATE KEY-----\nMIIEogIBAAKCAQEAhstYtRbkgQkFwlVr8QjSCQqqRTDMKWHdIGRYBpXcQmvKfagId9nBA2Ygh7cOrT9g8MhxYo8U1jYmPQpv6gf3LgO/J0qspLdaAhZP6LusA/HHJBR7kjTXBsLcsEDyd8S0UioBYP3DLvtWhGIR2f4o7SH1TlE96tldV6FZKGO2NHsJrJwTd+ym0AeZe0b7QZLe43LBCTLdqk05U34jrknJliSAEbGqYg4h6nrJsKBC/0pmiQ9ptD1N/Kl4bqffMWIbZq2bPP6jFrmBLe+7yTeVMKltVbJZys4nHhyYngBtbAxynXeB2tpE8If7cK75fj42MlFgquEiEZZVSzNNmrmPOwIDAQABAoH/B18Xes/Fr0jPB9GkFYpl8hijNyV0BM9VSHA0YCfR49ABQt3tmKBP7d+n58QbCV5t7r0Hdlxcx1ouvSfU9vd4jQunaH6s8lUUlwihVhjtT0npmg+EsnoxSC1f5EOo/uPC+LtTV/qIsgkMsjCqyUEc+9rfj2jh+fXpJOGt/od1b2k2xs84MsXmSF/As7GYRdw+FLbkN64R/SGmv3NLtQdg5uvBKLuKvtQWIJBuPqgKOsJWaCVO0XaoUDQeav/nTfP0ntmF0QH9JtXYzBldhGq2FPVQRUaCuJ4YPEpXlD3FptQBlX/Wu7wXbdwDz3qyXbGqSkiaR3gN+QR+IgjG3oQxAoGBAML5M4Dg0S/yobHuCRcvpngraXGBWnCTaD0mMh/cosV0HBNdZbglwVpG8Agz9BEYIrDM777HFuB+lWUvGNMR45rObPcDqn7Qj8Uwnj775Bg0Sx09MCBds6IGce/92uPUsHPx4pj8dzCj1s3cfUKO+EaUE33bnFXcMCGh/0x0sIVXAoGBALD8H4Aph2OPQK9OOHb3ULDvrmMPrpe3xv5iSzfLt7xBIP2G0Wl+q0hzEtdEOUZGQemOtyuV5t9Jwwfh9uH9jAhk9OEvoNg3F3mQl6hjmHPd1xUNvRTqwnV+VvQnw7Aeq2TZMcAKwbXf3+p430wMsxR6m0Y7rGi0FIxWbILp0RK9AoGBAIfiPBXnGYOsOysRtb42FHQN9WgI+eoZof10IFz6XWr12Bda8Wicz5vGcsWUx9YeFxdXTQOOJ5CASEiDwW5hOlqK4YBqSqolWv3YO4Gz9i00TOFs4py8EVSr3z6ekq5UbkHwY7exxLPei/dfYuE/WSN/UfJWWyev1M+r4oz7iobzAoGAKe8S56LvWT+P6/l0l3txuvqPLxmAHKKGm69ecxHprskfr/JJm91PaBMb27VmfKgY5eXSsJkL4svvUebQQCt7CmIhQ1mtmo0zGrKPvG4cqRde5rYintogyQXuRFtHmmsp4PM1PnNOAnHQ9BU/kx1PMQL712A8MXK5i6bOfxY3W2ECgYEAp9cw3NeMSy/WcXyZoyNFUdEQiHTJGPBtELjHWRnjMU1454EkWYYPiYXUnElfxP6InxHgMNbGVsd1BUEhXOdSUS5bO/WBOOPqSh6MIGfKFuMN/9SI/Y/UZKltCD1CboTvDfmkD+opkLM6YZpW9CRT7Szn7ivdFr5KqGQZUZOwn3k=\n-----END RSA PRIVATE KEY-----'
Run Code Online (Sandbox Code Playgroud)
或者
secret = '''-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAhstYtRbkgQkFwlVr8QjSCQqqRTDMKWHdIGRYBpXcQmvKfagId9nBA2Ygh7cOrT9g8MhxYo8U1jYmPQpv6gf3LgO/J0qspLdaAhZP6LusA/HHJBR7kjTXBsLcsEDyd8S0UioBYP3DLvtWhGIR2f4o7SH1TlE96tldV6FZKGO2NHsJrJwTd+ym0AeZe0b7QZLe43LBCTLdqk05U34jrknJliSAEbGqYg4h6nrJsKBC/0pmiQ9ptD1N/Kl4bqffMWIbZq2bPP6jFrmBLe+7yTeVMKltVbJZys4nHhyYngBtbAxynXeB2tpE8If7cK75fj42MlFgquEiEZZVSzNNmrmPOwIDAQABAoH/B18Xes/Fr0jPB9GkFYpl8hijNyV0BM9VSHA0YCfR49ABQt3tmKBP7d+n58QbCV5t7r0Hdlxcx1ouvSfU9vd4jQunaH6s8lUUlwihVhjtT0npmg+EsnoxSC1f5EOo/uPC+LtTV/qIsgkMsjCqyUEc+9rfj2jh+fXpJOGt/od1b2k2xs84MsXmSF/As7GYRdw+FLbkN64R/SGmv3NLtQdg5uvBKLuKvtQWIJBuPqgKOsJWaCVO0XaoUDQeav/nTfP0ntmF0QH9JtXYzBldhGq2FPVQRUaCuJ4YPEpXlD3FptQBlX/Wu7wXbdwDz3qyXbGqSkiaR3gN+QR+IgjG3oQxAoGBAML5M4Dg0S/yobHuCRcvpngraXGBWnCTaD0mMh/cosV0HBNdZbglwVpG8Agz9BEYIrDM777HFuB+lWUvGNMR45rObPcDqn7Qj8Uwnj775Bg0Sx09MCBds6IGce/92uPUsHPx4pj8dzCj1s3cfUKO+EaUE33bnFXcMCGh/0x0sIVXAoGBALD8H4Aph2OPQK9OOHb3ULDvrmMPrpe3xv5iSzfLt7xBIP2G0Wl+q0hzEtdEOUZGQemOtyuV5t9Jwwfh9uH9jAhk9OEvoNg3F3mQl6hjmHPd1xUNvRTqwnV+VvQnw7Aeq2TZMcAKwbXf3+p430wMsxR6m0Y7rGi0FIxWbILp0RK9AoGBAIfiPBXnGYOsOysRtb42FHQN9WgI+eoZof10IFz6XWr12Bda8Wicz5vGcsWUx9YeFxdXTQOOJ5CASEiDwW5hOlqK4YBqSqolWv3YO4Gz9i00TOFs4py8EVSr3z6ekq5UbkHwY7exxLPei/dfYuE/WSN/UfJWWyev1M+r4oz7iobzAoGAKe8S56LvWT+P6/l0l3txuvqPLxmAHKKGm69ecxHprskfr/JJm91PaBMb27VmfKgY5eXSsJkL4svvUebQQCt7CmIhQ1mtmo0zGrKPvG4cqRde5rYintogyQXuRFtHmmsp4PM1PnNOAnHQ9BU/kx1PMQL712A8MXK5i6bOfxY3W2ECgYEAp9cw3NeMSy/WcXyZoyNFUdEQiHTJGPBtELjHWRnjMU1454EkWYYPiYXUnElfxP6InxHgMNbGVsd1BUEhXOdSUS5bO/WBOOPqSh6MIGfKFuMN/9SI/Y/UZKltCD1CboTvDfmkD+opkLM6YZpW9CRT7Szn7ivdFr5KqGQZUZOwn3k=
-----END RSA PRIVATE KEY-----'''
Run Code Online (Sandbox Code Playgroud)
通过此更改,代码可以正常工作(在添加缺失的语句iam_url和缺失的import语句之后)。
请注意,PKCS8EncodedKeySpec在 Java 代码中需要 PKCS#8 格式的 DER 编码私钥,而在 Python 代码中应用 PKCS#1 格式的 PEM 编码私钥。
通过删除页眉、页脚和所有换行符并对其余部分进行 Base64 解码,可以从 PEM 编码密钥生成 DER 编码密钥。密码学库支持导入 DER 编码的私钥load_der_private_key():
import base64
secret = base64.b64decode('MIIEogIBAAKCAQEAhstYtRbkgQkFwlVr8QjSCQqqRTDMKWHdIGRYBpXcQmvKfagId9nBA2Ygh7cOrT9g8MhxYo8U1jYmPQpv6gf3LgO/J0qspLdaAhZP6LusA/HHJBR7kjTXBsLcsEDyd8S0UioBYP3DLvtWhGIR2f4o7SH1TlE96tldV6FZKGO2NHsJrJwTd+ym0AeZe0b7QZLe43LBCTLdqk05U34jrknJliSAEbGqYg4h6nrJsKBC/0pmiQ9ptD1N/Kl4bqffMWIbZq2bPP6jFrmBLe+7yTeVMKltVbJZys4nHhyYngBtbAxynXeB2tpE8If7cK75fj42MlFgquEiEZZVSzNNmrmPOwIDAQABAoH/B18Xes/Fr0jPB9GkFYpl8hijNyV0BM9VSHA0YCfR49ABQt3tmKBP7d+n58QbCV5t7r0Hdlxcx1ouvSfU9vd4jQunaH6s8lUUlwihVhjtT0npmg+EsnoxSC1f5EOo/uPC+LtTV/qIsgkMsjCqyUEc+9rfj2jh+fXpJOGt/od1b2k2xs84MsXmSF/As7GYRdw+FLbkN64R/SGmv3NLtQdg5uvBKLuKvtQWIJBuPqgKOsJWaCVO0XaoUDQeav/nTfP0ntmF0QH9JtXYzBldhGq2FPVQRUaCuJ4YPEpXlD3FptQBlX/Wu7wXbdwDz3qyXbGqSkiaR3gN+QR+IgjG3oQxAoGBAML5M4Dg0S/yobHuCRcvpngraXGBWnCTaD0mMh/cosV0HBNdZbglwVpG8Agz9BEYIrDM777HFuB+lWUvGNMR45rObPcDqn7Qj8Uwnj775Bg0Sx09MCBds6IGce/92uPUsHPx4pj8dzCj1s3cfUKO+EaUE33bnFXcMCGh/0x0sIVXAoGBALD8H4Aph2OPQK9OOHb3ULDvrmMPrpe3xv5iSzfLt7xBIP2G0Wl+q0hzEtdEOUZGQemOtyuV5t9Jwwfh9uH9jAhk9OEvoNg3F3mQl6hjmHPd1xUNvRTqwnV+VvQnw7Aeq2TZMcAKwbXf3+p430wMsxR6m0Y7rGi0FIxWbILp0RK9AoGBAIfiPBXnGYOsOysRtb42FHQN9WgI+eoZof10IFz6XWr12Bda8Wicz5vGcsWUx9YeFxdXTQOOJ5CASEiDwW5hOlqK4YBqSqolWv3YO4Gz9i00TOFs4py8EVSr3z6ekq5UbkHwY7exxLPei/dfYuE/WSN/UfJWWyev1M+r4oz7iobzAoGAKe8S56LvWT+P6/l0l3txuvqPLxmAHKKGm69ecxHprskfr/JJm91PaBMb27VmfKgY5eXSsJkL4svvUebQQCt7CmIhQ1mtmo0zGrKPvG4cqRde5rYintogyQXuRFtHmmsp4PM1PnNOAnHQ9BU/kx1PMQL712A8MXK5i6bOfxY3W2ECgYEAp9cw3NeMSy/WcXyZoyNFUdEQiHTJGPBtELjHWRnjMU1454EkWYYPiYXUnElfxP6InxHgMNbGVsd1BUEhXOdSUS5bO/WBOOPqSh6MIGfKFuMN/9SI/Y/UZKltCD1CboTvDfmkD+opkLM6YZpW9CRT7Szn7ivdFr5KqGQZUZOwn3k=')
priv_rsakey = serialization.load_der_private_key(secret, password=None, backend=default_backend())
Run Code Online (Sandbox Code Playgroud)
load_pem_private_key()并load_der_private_key()支持 PKCS#8 和 PKCS#1 格式。
| 归档时间: |
|
| 查看次数: |
9188 次 |
| 最近记录: |