从AWS Secrets获取PEM生成JWT遇编码错误,如何解决?
问题
我正在构建一个AWS Lambda,用于通过PEM生成JWT。从本地文件读取PEM时一切正常,代码如下:
# Open PEM with open(pem, 'rb') as pem_file: signing_key = jwt.jwk_from_pem(pem_file.read())
但从AWS Secrets Manager获取PEM内容时出现错误,相关代码:
# get PEM from AWS secret secret = get_secret() signing_key = jwt.jwk_from_pem(secret)
报错信息:
{ "errorMessage": "from_buffer() cannot return the address of a unicode object", "errorType": "TypeError", "stackTrace": [ " File \"/var/task/handler.py\", line 19, in handler\n signing_key = jwt.jwk_from_pem(secret)\n", " File \"/var/task/jwt/jwk.py\", line 405, in jwk_from_pem\n return jwk_from_bytes(\n", " File \"/var/task/jwt/jwk.py\", line 384, in jwk_from_bytes\n return jwk_from_private_bytes(\n", " File \"/var/task/jwt/jwk.py\", line 328, in wrapper\n return func(content, loader, **kwargs)\n", " File \"/var/task/jwt/jwk.py\", line 345, in jwk_from_private_bytes\n privkey = private_loader(content, password, backend) # type: ignore[operator] # noqa: E501\n", " File \"/var/task/cryptography/hazmat/primitives/serialization/base.py\", line 24, in load_pem_private_key\n return ossl.load_pem_private_key(\n", " File \"/var/task/cryptography/hazmat/backends/openssl/backend.py\", line 949, in load_pem_private_key\n return self._load_key(\n", " File \"/var/task/cryptography/hazmat/backends/openssl/backend.py\", line 1169, in _load_key\n mem_bio = self._bytes_to_bio(data)\n", " File \"/var/task/cryptography/hazmat/backends/openssl/backend.py\", line 630, in _bytes_to_bio\n data_ptr = self._ffi.from_buffer(data)\n" ] }
get_secret函数代码:
def get_secret(): secret_name = "pem" region_name = "eu-west-1" # Create a Secrets Manager client session = boto3.session.Session() client = session.client( service_name='secretsmanager', region_name=region_name ) try: get_secret_value_response = client.get_secret_value( SecretId=secret_name ) except ClientError as e: # For a list of exceptions thrown, see # https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html raise e # Decrypts secret using the associated KMS key. secret = json.loads(get_secret_value_response['SecretString']) return (secret['pem'])
解决建议
核心原因
从AWS Secrets Manager获取的PEM内容是字符串类型(Unicode),而jwt.jwk_from_pem()需要的是字节流(bytes)——本地读取文件时用'rb'模式直接拿到了字节,所以能正常运行。
修复方案
将字符串编码为字节:
在调用jwk_from_pem()前,把获取到的PEM字符串用utf-8编码转为字节:secret = get_secret() # 编码为字节流 signing_key = jwt.jwk_from_pem(secret.encode('utf-8'))验证PEM格式正确性:
确保AWS Secrets中存储的PEM内容格式完整:- 包含首尾标记:
-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY----- - 换行符正确(部分场景下存储时会丢失换行,导致PEM格式无效)
- 包含首尾标记:
内容的提问来源于stack exchange,提问作者Andres
相关产品推荐
相关产品推荐

