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字符串
验证流程
- 用修正后的NextJS代码加密测试数据,得到Base64字符串
- 通过Postman或NextJS请求将该字符串发送给Python API
- 检查API返回的解密结果是否与原始测试数据一致
内容的提问来源于stack exchange,提问作者Daniel Acosta
相关产品推荐
相关产品推荐

