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

Node.js中如何使用公钥加密Buffer类型大文件并返回Base64

错误原因

RSA非对称加密存在固有长度限制:仅能加密长度小于密钥长度的明文。如果你使用默认的PKCS#1 OAEP填充,最大可加密的明文长度计算公式为:密钥长度(bit)/8 - 2*哈希算法输出长度(字节) - 2,以常用的2048位RSA密钥+SHA256哈希为例,最大仅能加密190字节的明文,内容超过长度就会抛出该错误。

解决方案

大体积内容不要直接使用RSA加密,采用混合加密方案即可,全程内存操作无需落盘,逻辑如下:

  • 随机生成一个对称加密密钥(推荐使用AES-256-GCM,安全性高且自带内容完整性校验)
  • 用生成的对称密钥加密整个Buffer格式的文件内容
  • 用你持有的RSA公钥加密这个对称密钥
  • 把加密后的对称密钥、AES加密所需的IV、AES加密验证标签、加密后的文件内容按固定顺序拼接后转Base64返回即可

实现代码

import { createCipheriv, randomBytes, publicEncrypt } from 'crypto'

// 加密参数配置,可根据需求调整,AES-256-GCM要求密钥长度固定为32字节
const SYMMETRIC_ALGORITHM = 'aes-256-gcm'
const SYMMETRIC_KEY_LENGTH = 32
const IV_LENGTH = 12 // GCM模式官方推荐使用12字节IV,性能和安全性最优

function encrypt(fileInBuffer: Buffer, publicKey: string): string {
  // 1. 生成随机对称密钥和IV
  const symmetricKey = randomBytes(SYMMETRIC_KEY_LENGTH)
  const iv = randomBytes(IV_LENGTH)

  // 2. 用对称密钥加密完整文件Buffer
  const cipher = createCipheriv(SYMMETRIC_ALGORITHM, symmetricKey, iv)
  const encryptedFile = Buffer.concat([cipher.update(fileInBuffer), cipher.final()])
  const authTag = cipher.getAuthTag() // GCM模式验证标签,解密时需用来校验内容是否被篡改

  // 3. 用RSA公钥加密对称密钥
  const encryptedSymmetricKey = publicEncrypt(publicKey, symmetricKey)

  // 4. 按固定格式拼接所有内容:[加密对称密钥长度(4字节) | 加密对称密钥 | IV | 验证标签 | 加密文件内容]
  const result = Buffer.concat([
    // 前4位存加密后对称密钥的长度,解密时用来拆分内容
    Buffer.from([
      encryptedSymmetricKey.length >> 24, 
      encryptedSymmetricKey.length >> 16, 
      encryptedSymmetricKey.length >> 8, 
      encryptedSymmetricKey.length
    ]),
    encryptedSymmetricKey,
    iv,
    authTag,
    encryptedFile
  ])

  return result.toString('base64')
}

注意:不建议采用RSA分段加密的方案,RSA加密计算效率远低于对称加密,大文件分段加密会产生极大的性能开销,且密文体积会膨胀数倍,混合加密是行业通用的标准方案。

解密时只需按拼接顺序拆分各部分内容,先用RSA私钥解密得到对称密钥,再用对称密钥解密文件内容即可。

内容的提问来源于stack exchange,提问作者Marcin Warzybok

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:45:02