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

Node.js RSA加密报错:数据大小超出密钥长度限制

解决RSA加密大文本时的"data too large for key size"错误

问题原因

RSA是非对称加密算法,天生不适合加密大体积数据。对于2048位的RSA密钥,使用默认的PKCS1-OAEP填充时,最大可加密的明文长度计算公式为:
最大明文长度 = 密钥长度(字节) - 2*哈希算法输出长度 - 2
以默认的SHA-256哈希为例,2048位密钥对应256字节,最大明文长度为 256 - 2*32 - 2 = 190字节,远小于你要加密的2224字节字符串,因此触发报错。

直接使用RSA_NO_PADDING不可行:该模式要求明文长度必须与RSA模长完全一致(256字节),且无填充的RSA加密安全性极低,同时Node.js的crypto模块对无填充模式的使用有严格限制,容易触发无效填充错误。

正确解决方案:混合加密

采用非对称加密+对称加密的混合方案:

  1. 生成一个临时的对称加密密钥(如AES-256-GCM)
  2. 用对称密钥加密大体积的目标字符串
  3. 用RSA公钥加密这个对称密钥
  4. 将加密后的对称密钥和加密后的文本一起传输/存储
  5. 解密时,先用RSA私钥解密出对称密钥,再用对称密钥解密文本

代码实现

加密流程

const crypto = require('crypto');

// 假设已生成RSA密钥对
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
    modulusLength: 2048,
    publicKeyEncoding: { type: 'spki', format: 'pem' },
    privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
});

// 要加密的大字符串(长度2224)
const str = '...'; // 你的目标字符串

// 1. 生成AES密钥和初始化向量(IV)
const aesKey = crypto.randomBytes(32); // AES-256需要32字节密钥
const iv = crypto.randomBytes(12); // GCM模式推荐12字节IV

// 2. 用AES-GCM加密大文本
const aesCipher = crypto.createCipheriv('aes-256-gcm', aesKey, iv);
let encryptedText = aesCipher.update(str, 'utf8', 'base64');
encryptedText += aesCipher.final('base64');
const authTag = aesCipher.getAuthTag().toString('base64'); // GCM需要验证标签

// 3. 用RSA公钥加密AES密钥
const encryptedAesKey = crypto.publicEncrypt(
    {
        key: publicKey,
        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING, // 默认填充,安全
        oaepHash: 'sha256',
    },
    aesKey
).toString('base64');

// 最终输出:加密后的AES密钥 + IV + 加密文本 + 验证标签
const encryptedPackage = {
    encryptedAesKey,
    iv: iv.toString('base64'),
    encryptedText,
    authTag
};

解密流程

// 从encryptedPackage中取出各部分数据
const { encryptedAesKey, iv, encryptedText, authTag } = encryptedPackage;

// 1. 用RSA私钥解密AES密钥
const decryptedAesKey = crypto.privateDecrypt(
    {
        key: privateKey,
        padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
        oaepHash: 'sha256',
    },
    Buffer.from(encryptedAesKey, 'base64')
);

// 2. 用AES-GCM解密文本
const aesDecipher = crypto.createDecipheriv(
    'aes-256-gcm',
    decryptedAesKey,
    Buffer.from(iv, 'base64')
);
aesDecipher.setAuthTag(Buffer.from(authTag, 'base64'));

let decryptedText = aesDecipher.update(encryptedText, 'base64', 'utf8');
decryptedText += aesDecipher.final('utf8');

console.log(decryptedText); // 还原后的原始字符串

关键说明

  • AES-GCM是认证加密模式,相比ECB/CBC更安全,能同时保证机密性和完整性
  • 每次加密都要生成新的IV和AES密钥,避免重复使用导致安全风险
  • 不要尝试修改RSA填充模式来适配大文本,这会严重降低加密安全性

内容的提问来源于stack exchange,提问作者Hrishikesh Vaze

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 00:52:42