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

RSA-OAEP加密超过190字节数据报错,大数据加密的正确方案是什么?

报错原因

RSA 非对称加密本身的设计定位就是加密小长度数据,不存在加密任意长度明文的实现方案,你遇到的长度限制是标准特性:
2048位的RSA密钥配合RSA-OAEP、SHA-256参数时,最大可加密的明文长度为 2048/8 - 2*32 - 2 = 190 字节,超过这个长度就会抛出加密异常。

大体积数据加密的标准实现方案

业内通用的做法是混合加密,结合非对称加密的安全性和对称加密的高性能、无长度限制特性,流程如下:

  • 生成随机的对称加密密钥,推荐使用AES-GCM算法(自带完整性校验,安全等级更高)
  • 用生成的AES密钥加密需要处理的大体积明文
  • 用RSA公钥加密这个AES对称密钥
  • 最终传输/存储的加密内容由三部分拼接组成:RSA加密后的AES密钥、AES加密使用的随机IV、AES加密得到的密文
    解密时反向操作即可:先拆分得到三个部分,用RSA私钥解密得到AES密钥,再用AES密钥+IV解密密文得到原始数据。
完整实现示例
// 生成RSA密钥对,和原有逻辑一致
async function generateRsaKeyPair() {
  return crypto.subtle.generateKey({
    name: "RSA-OAEP",
    modulusLength: 2048,
    publicExponent: new Uint8Array([1, 0, 1]),
    hash: "SHA-256",
  }, true, ["encrypt", "decrypt"])
}

// 加密任意长度数据
async function encryptData(publicKey, rawData) {
  // 1. 生成AES-GCM密钥
  const aesKey = await crypto.subtle.generateKey(
    { name: "AES-GCM", length: 256 },
    true,
    ["encrypt", "decrypt"]
  )
  // 2. 生成随机IV,AES-GCM推荐用12字节IV
  const iv = crypto.getRandomValues(new Uint8Array(12))
  // 3. 用AES加密原始数据
  const encryptedContent = await crypto.subtle.encrypt(
    { name: "AES-GCM", iv: iv },
    aesKey,
    rawData
  )
  // 4. 导出AES密钥的原始二进制格式
  const rawAesKey = await crypto.subtle.exportKey("raw", aesKey)
  // 5. 用RSA公钥加密AES密钥
  const encryptedAesKey = await crypto.subtle.encrypt(
    { name: "RSA-OAEP" },
    publicKey,
    rawAesKey
  )
  // 6. 拼接所有结果返回:加密的AES密钥(256字节) + IV(12字节) + 加密内容
  const result = new Uint8Array(encryptedAesKey.byteLength + iv.byteLength + encryptedContent.byteLength)
  result.set(new Uint8Array(encryptedAesKey), 0)
  result.set(iv, encryptedAesKey.byteLength)
  result.set(new Uint8Array(encryptedContent), encryptedAesKey.byteLength + iv.byteLength)
  return result
}

// 解密数据
async function decryptData(privateKey, encryptedData) {
  // 拆分数据,长度对应加密时的规则
  const encryptedAesKey = encryptedData.slice(0, 256)
  const iv = encryptedData.slice(256, 256 + 12)
  const encryptedContent = encryptedData.slice(256 + 12)
  // 1. RSA解密得到AES密钥
  const rawAesKey = await crypto.subtle.decrypt(
    { name: "RSA-OAEP" },
    privateKey,
    encryptedAesKey
  )
  // 2. 导入AES密钥
  const aesKey = await crypto.subtle.importKey(
    "raw",
    rawAesKey,
    { name: "AES-GCM", length: 256 },
    true,
    ["encrypt", "decrypt"]
  )
  // 3. AES解密得到原始数据
  const rawData = await crypto.subtle.decrypt(
    { name: "AES-GCM", iv: iv },
    aesKey,
    encryptedContent
  )
  return rawData
}

// 测试用例
async function test(size) {
  const keyPair = await generateRsaKeyPair()
  const rawData = new Uint8Array(size)
  try {
    const encrypted = await encryptData(keyPair.publicKey, rawData)
    const decrypted = await decryptData(keyPair.privateKey, encrypted)
    console.log(`${size}字节加密成功,解密后长度匹配:${decrypted.byteLength === size}`)
  } catch (ex) {
    console.log(`${size}字节加密失败:${ex.constructor.name} ${ex}`)
  }
}

test(191) // 成功
test(500) // 成功
test(1024 * 1024) // 1MB数据也可正常加密

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 11:06:08