You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python生产环境RSA私钥加载失败求助(本地运行正常)

问题:本地正常的单行RSA私钥在生产环境加载失败

本地.env文件中,RSA私钥以单行格式存储,格式如下:

PRIVATE_KEY=\"-----BEGIN RSA PRIVATE KEY-----\ncontentsofkey\n-----END RSA PRIVATE KEY-----\n\"

每64个字符包含一个\n转义换行符,Python应用本地运行正常。

但将完全相同的单行私钥复制到GitHub Secrets后,生产环境抛出以下错误:

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).', [<OpenSSLError(code=503841036, lib=60, reason=524556, reason_text=unsupported)>])

During handling of the above exception, another exception occurred:

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).', [<OpenSSLError(code=75497580, lib=9, reason=108, reason_text=no start line)>])

错误提示私钥格式不支持且无起始行,但生产环境使用与本地完全相同的Python版本和requirements.txt。在load_pem_private_key()前添加打印语句,显示生产环境的私钥格式与本地.env文件完全一致:

\"-----BEGIN RSA PRIVATE KEY-----\ncontentsofkey\n-----END RSA PRIVATE KEY-----\n\"

由于GitHub Actions工作流会因多行私钥抛出YAML语法错误,必须以单行存储私钥。


相关配置与代码

  1. Python加密代码(本地正常运行)
now = int(time.time())
payload = {"iat": now, "exp": now + expiration, "iss": self.id}
print(self.key)
# 下方代码抛出上述错误
encrypted = jwt.encode(payload, key=self.key, algorithm="RS256")

if isinstance(encrypted, bytes):
    encrypted = encrypted.decode("utf-8")
return encrypted

错误由cryptography包的_handle_key_loading_error为load_pem_public_key抛出。

  1. GitHub工作流配置
- name: Deploy secrets
  if: ${{ github.event_name == 'release' || github.event_name == 'workflow_dispatch' }}
  run:  |
    eval "echo \"$(cat .deployment/secret.yaml)\"" | kubectl apply -f -
  env: 
    GITHUBAPP_KEY: '${{ secrets.PRIVATE_KEY }}'
  1. K8s Secret部署文件
apiVersion: v1
kind: Secret
metadata:
  name: xxx
  namespace: xxx
type: Opaque
stringData:
  GITHUBAPP_KEY: '${GITHUBAPP_KEY}'
  1. Python读取密钥方式
app.config["GITHUBAPP_KEY"] = environ["GITHUBAPP_KEY"]

解决方法

原因分析

本地.env文件中,\n会被Python的environ自动解析为实际换行符;但在GitHub Secrets → GitHub Actions → K8s Secret的传递过程中,\n被当作普通字符串传递,未被解析为实际换行符。最终Python拿到的私钥是包含\n文本的字符串,而非标准换行的PEM格式,导致cryptography无法识别密钥起始行。

解决步骤

  1. 修改Python代码,手动解析转义换行符
    在读取密钥后,先处理转义字符并去除可能的外层引号:
raw_key = environ["GITHUBAPP_KEY"]
# 去除前后的引号(如果存在),并将转义的\n替换为实际换行符
processed_key = raw_key.strip('"').replace('\\n', '\n')
app.config["GITHUBAPP_KEY"] = processed_key
  1. 修正GitHub Secrets中的私钥格式
    去掉本地.env中的外层引号,直接存储单行私钥:
-----BEGIN RSA PRIVATE KEY-----\ncontentsofkey\n-----END RSA PRIVATE KEY-----\n
  1. 优化GitHub Actions的变量传递逻辑
    替换eval为envsubst避免转义问题,修改工作流配置:
run: |
  envsubst < .deployment/secret.yaml | kubectl apply -f -

同时调整K8s Secret文件的变量引用,去掉外层单引号:

stringData:
  GITHUBAPP_KEY: ${GITHUBAPP_KEY}

经过以上处理,Python将拿到标准格式的PEM私钥,cryptography即可正常加载并使用。


内容的提问来源于stack exchange,提问作者yung peso

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:52:09