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

如何用Python通过RSA公钥加密JWT数据?解决类型错误问题

解决Python RSA加密JWT时的TypeError问题

错误原因分析

抛出的TypeError: can't concat str to bytes核心原因是:PyCryptodome的PKCS1_OAEP加密方法要求输入必须是字节流(bytes),但你传入的JWT字符串是str类型,导致底层拼接字节与字符串时出错。

此外代码还有三个隐性问题:

  • 分段加密长度设置不合理:PKCS1_OAEP的最大明文分段长度为密钥位数//8 - 42(比如2048位密钥对应214字节),硬写20既浪费性能也不符合RSA加密规范。
  • 结果拼接方式错误:加密后的分段是bytes类型,不能用字符串的"".join(),会引发类型错误;且PHP返回的是Base64编码结果,Python代码需对应处理。
  • main函数中key变量未定义,需补充合法的RSA公钥内容。

修正后的代码

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
import base64

def rsa_long_encrypt(key_, msg, length=None):
    key = RSA.importKey(key_)
    cipher = PKCS1_OAEP.new(key)
    # 计算PKCS1_OAEP允许的最大明文分段长度
    max_block_size = key.size_in_bytes() - 42
    if length is None or length > max_block_size:
        length = max_block_size
    
    # 将字符串转换为UTF-8字节流
    msg_bytes = msg.encode('utf-8')
    res = []
    for i in range(0, len(msg_bytes), length):
        msg_to_en = msg_bytes[i:i+length]
        ciphertext = cipher.encrypt(msg_to_en)
        res.append(ciphertext)
    
    # 拼接字节分段并Base64编码,与PHP输出格式对齐
    encrypted_bytes = b''.join(res)
    return base64.b64encode(encrypted_bytes).decode('utf-8')

if __name__ == "__main__":
    # 替换为实际使用的RSA公钥(需带完整的BEGIN/END标识)
    public_key = """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
(此处省略完整公钥内容)
-----END PUBLIC KEY-----"""
    message = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'
    enres = rsa_long_encrypt(public_key, message)
    print(enres)

关键修改说明

  • 字符串转字节:用encode('utf-8')将JWT字符串转为字节流,满足encrypt()方法的参数要求。
  • 动态计算分段长度:根据密钥自动计算最大允许的明文长度,避免硬编码导致的兼容性问题。
  • 结果格式对齐:用b''.join()拼接字节分段,再通过base64.b64encode()编码为字符串,与PHP输出的Base64格式匹配。
  • 补充公钥定义:在main函数中添加了公钥示例,需替换为实际的RSA公钥内容。

一致性验证注意事项

要确保Python代码与PHP代码使用相同的RSA公钥、相同的哈希算法(PKCS1_OAEP默认用SHA-1,若PHP使用SHA-256等其他哈希,需在Python中指定:PKCS1_OAEP.new(key, hashAlgo=SHA256.new())),才能得到一致的加密结果。

内容的提问来源于stack exchange,提问作者mosa lorans

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 10:01:13