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

NextJS端加密数据无法在Python API正常解密问题排查

解决NextJS客户端RSA加密后Python API无法解密的问题

核心问题分析

解密失败的核心原因集中在NextJS端的加密实现上,主要存在以下几个问题:

  • 使用了非法格式的RSA公钥(普通字符串而非标准PEM格式)
  • 若在浏览器端(NextJS客户端组件)使用NodeJS的crypto模块,存在环境兼容性问题
  • 加密时未明确指定数据编码,导致字节转换异常

修正方案

1. 生成合法的RSA密钥对

首先需要生成标准PEM格式的RSA密钥对,可通过openssl命令完成:

# 生成2048位私钥
openssl genrsa -out private_key.pem 2048
# 从私钥导出对应的公钥
openssl rsa -in private_key.pem -pubout -out public_key.pem

将生成的public_key.pem内容用于NextJS端加密,private_key.pem放在Python API的./secure/目录下。

2. 修正NextJS端加密代码

根据运行环境选择对应的实现:

情况A:NextJS服务器端/API路由(NodeJS环境)
const crypto = require('crypto');

function encryptData(data) {
    // 替换为你的PEM格式公钥内容
    const publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----`;

    const encryptedData = crypto.publicEncrypt({
        key: publicKey,
        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
        oaepHash: 'sha256'
    }, Buffer.from(data, 'utf-8')); // 明确指定UTF-8编码

    return encryptedData.toString('base64');
}
情况B:NextJS客户端组件(浏览器环境)

浏览器不支持NodeJS的crypto模块,需使用Web Crypto API:

async function encryptData(data, publicKeyPem) {
    // 解析PEM公钥为Web Crypto支持的格式
    const publicKey = await window.crypto.subtle.importKey(
        'spki',
        pemToArrayBuffer(publicKeyPem),
        { name: 'RSA-OAEP', hash: 'SHA-256' },
        false,
        ['encrypt']
    );

    // 加密数据
    const encodedData = new TextEncoder().encode(data);
    const encryptedBuffer = await window.crypto.subtle.encrypt(
        { name: 'RSA-OAEP' },
        publicKey,
        encodedData
    );

    return bufferToBase64(encryptedBuffer);
}

// PEM字符串转ArrayBuffer辅助函数
function pemToArrayBuffer(pem) {
    const cleanPem = pem.replace(/-----BEGIN PUBLIC KEY-----/, '')
                        .replace(/-----END PUBLIC KEY-----/, '')
                        .replace(/\s/g, '');
    const byteString = atob(cleanPem);
    const arrayBuffer = new ArrayBuffer(byteString.length);
    const uint8Array = new Uint8Array(arrayBuffer);
    for (let i = 0; i < byteString.length; i++) {
        uint8Array[i] = byteString.charCodeAt(i);
    }
    return arrayBuffer;
}

// ArrayBuffer转Base64辅助函数
function bufferToBase64(buffer) {
    const uint8Array = new Uint8Array(buffer);
    let binary = '';
    for (let i = 0; i < uint8Array.length; i++) {
        binary += String.fromCharCode(uint8Array[i]);
    }
    return btoa(binary);
}

3. Python端代码验证

你的Python解密代码本身逻辑正确,只需确保:

  • private_key.pem是与NextJS端公钥对应的私钥
  • 传入的b64data是正确的Base64字符串

验证流程

  1. 用修正后的NextJS代码加密测试数据,得到Base64字符串
  2. 通过Postman或NextJS请求将该字符串发送给Python API
  3. 检查API返回的解密结果是否与原始测试数据一致

内容的提问来源于stack exchange,提问作者Daniel Acosta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 02:23:19