​RSA 加密数据过长导致解密结果为 null

RSA 加密对数据长度有限制,通常加密数据不能超过密钥长度(如 1024 位密钥最多加密 117 字节数据)。如果数据过长,会导致解密失败。解决方法是通过分段加密分段解密

分段加密解密步骤:
  1. 分段加密

    • 将数据按固定长度(如 117 字节)分段。
    • 对每段数据进行 RSA 加密。
    • 将加密后的分段数据拼接成完整的密文。
  2. 分段解密

    • 将密文按固定长度(如 128 字节)分段。
    • 对每段数据进行 RSA 解密。
    • 将解密后的分段数据拼接成完整的明文。

示例:

// 分段加密
function encryptLongData(data, publicKey) {
  const encryptor = new JSEncrypt();
  encryptor.setPublicKey(publicKey);
  let encrypted = '';
  let offset = 0;
  const blockSize = 117; // 分段长度
  while (offset < data.length) {
    const chunk = data.slice(offset, offset + blockSize);
    encrypted += encryptor.encrypt(chunk);
    offset += blockSize;
  }
  return encrypted;
}

// 分段解密
function decryptLongData(encryptedData, privateKey) {
  const decryptor = new JSEncrypt();
  decryptor.setPrivateKey(privateKey);
  let decrypted = '';
  let offset = 0;
  const blockSize = 128; // 分段长度
  while (offset < encryptedData.length) {
    const chunk = encryptedData.slice(offset, offset + blockSize);
    decrypted += decryptor.decrypt(chunk);
    offset += blockSize;
  }
  return decrypted;
}

 

2. ​中文数据加密后出现乱码

RSA 加密过程中,如果直接对中文字符进行加密,可能会因编码问题导致乱码。解决方法是在加密前对数据进行 ​encodeURIComponent编码,解密后再进行 ​decodeURIComponent解码。
 

  1. 后台加密前

    • 使用 encodeURIComponent 对数据进行编码。
    • 将编码后的数据转换为字节数组。
    • 对字节数组进行 RSA 加密。
    • 将加密结果转换为 Base64 字符串。
  2. 前端解密后

    • 对 Base64 字符串进行 RSA 解密。
    • 将解密结果转换为字符串。
    • 使用 decodeURIComponent 对字符串解码。
    • 使用 JSON.parse 将解码后的字符串转换为对象。

示例:

// 后台加密前
function encryptData(data, publicKey) {
  const encodedData = encodeURIComponent(JSON.stringify(data));
  const encryptor = new JSEncrypt();
  encryptor.setPublicKey(publicKey);
  return encryptor.encrypt(encodedData);
}

// 前端解密后
function decryptData(encryptedData, privateKey) {
  const decryptor = new JSEncrypt();
  decryptor.setPrivateKey(privateKey);
  const decodedData = decryptor.decrypt(encryptedData);
  return JSON.parse(decodeURIComponent(decodedData));
}

 如果不想手动实现分段加密解密,可以使用 jsencrypt-ext 库。它是对 jsencrypt 的扩展,支持长数据分段加密解密,且兼容中文编码。
安装与使用:

npm install jsencrypt-ext

import JSEncryptExt from 'jsencrypt-ext';

const encryptor = new JSEncryptExt();
encryptor.setPublicKey(publicKey);
const encrypted = encryptor.encryptLong(data);

const decryptor = new JSEncryptExt();
decryptor.setPrivateKey(privateKey);
const decrypted = decryptor.decryptLong(encrypted);