在 TypeScript 项目中使用 jsencrypt-plus(适配长文本加密的扩展库)时,需重点关注库的引入方式、类型声明兼容性以及分段加密的实现。以
一、安装与引入
-
安装库
通过 npm 安装jsencrypt-plus
或其衍生版本(如jsencrypt-plus-vite
):npm install jsencrypt-plus
若库未提供 TypeScript 类型声明文件(
.d.ts
),需在项目中手动声明类型。 -
类型声明扩展
在global.d.ts
或项目类型声明文件中添加以下内容:declare module 'jsencrypt-plus' { interface JSEncryptPlus { encryptLong: (text: string) => string; decryptLong: (text: string) => string; setPublicKey: (key: string) => void; setPrivateKey: (key: string) => void; } class JSEncrypt { constructor(); encryptLong: (text: string) => string; decryptLong: (text: string) => string; setPublicKey: (key: string) => void; setPrivateKey: (key: string) => void; } export default JSEncrypt; }
二、基础使用示例
1. 初始化与密钥配置
import JSEncrypt from 'jsencrypt-plus';
// 初始化实例
const encryptor = new JSEncrypt();
// 设置公钥(加密用)
const publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...公钥内容...
-----END PUBLIC KEY-----`;
encryptor.setPublicKey(publicKey);
// 设置私钥(解密用,通常仅后端使用)
const privateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEA...私钥内容...
-----END RSA PRIVATE KEY-----`;
encryptor.setPrivateKey(privateKey);
2. 加密与解密
// 加密长文本
const plainText = "需要加密的长文本(如包含中文的敏感数据)";
const encryptedData = encryptor.encryptLong(plainText);
console.log("加密结果:", encryptedData);
// 解密长文本
const decryptedData = encryptor.decryptLong(encryptedData);
console.log("解密结果:", decryptedData);
三、分段加密的底层实现(可选)
若需手动实现分段逻辑(如适配特殊密钥长度),可参考以下代码:
const MAX_ENCRYPT_BLOCK = 117; // RSA 2048密钥默认分段长度
function encryptLongText(text: string, publicKey: string): string {
const encryptor = new JSEncrypt();
encryptor.setPublicKey(publicKey);
let encrypted = "";
let offset = 0;
while (offset < text.length) {
const chunk = text.substring(offset, offset + MAX_ENCRYPT_BLOCK);
const encChunk = encryptor.encrypt(chunk);
if (!encChunk) throw new Error("加密失败");
encrypted += encChunk;
offset += MAX_ENCRYPT_BLOCK;
}
return encrypted;
}
四、与后端交互
1. 加密传输示例
async function sendEncryptedData(data: Record<string, any>) {
// 获取后端公钥
const publicKey = await fetchPublicKeyFromServer();
const encryptor = new JSEncrypt();
encryptor.setPublicKey(publicKey);
// 加密数据
const encryptedParams = encryptor.encryptLong(JSON.stringify(data));
// 发送请求
const response = await fetch('/api/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ encryptedData: encryptedParams }),
});
return response.json();
}
2. 后端解密建议
后端需使用对应私钥分段解密,确保与前端分段逻辑一致(如密钥长度匹配)。
五、常见问题解决
-
类型报错:
Module not found
确保安装的库版本支持 TypeScript,或通过// @ts-ignore
临时忽略类型检查。 -
中文乱码
加密前对文本进行 URI 编码,解密后解码:const encrypted = encryptor.encryptLong(encodeURIComponent(text)); const decrypted = decodeURIComponent(encryptor.decryptLong(encrypted));
-
加密返回
false
- 检查公钥格式是否正确(含
BEGIN/END PUBLIC KEY
标记)。 - 确认未加密空值或超长文本(使用
encryptLong
方法)。
- 检查公钥格式是否正确(含
六、性能优化
- iOS 解密延迟:结合 Web Worker 将解密任务移至子线程[citation:历史回答]。
- 混合加密:使用 RSA 加密 AES 密钥,再用 AES 加密数据,提升效率。