js实现rsa加密
RSA加密的基本原理
RSA是一种非对称加密算法,基于大整数分解的数学难题。它使用公钥加密数据,私钥解密数据,常用于数据传输加密和数字签名。
生成RSA密钥对
使用JavaScript生成RSA密钥对通常需要借助Web Crypto API:
async function generateKeyPair() {
return await window.crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 2048,
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
hash: "SHA-256"
},
true,
["encrypt", "decrypt"]
);
}
公钥加密数据
使用公钥加密字符串数据:
async function encryptData(publicKey, data) {
const encoded = new TextEncoder().encode(data);
return await window.crypto.subtle.encrypt(
{
name: "RSA-OAEP"
},
publicKey,
encoded
);
}
私钥解密数据
使用私钥解密加密后的数据:
async function decryptData(privateKey, encryptedData) {
const decrypted = await window.crypto.subtle.decrypt(
{
name: "RSA-OAEP"
},
privateKey,
encryptedData
);
return new TextDecoder().decode(decrypted);
}
完整示例流程
async function rsaExample() {
// 生成密钥对
const keyPair = await generateKeyPair();
// 原始数据
const originalData = "Secret message";
// 加密
const encrypted = await encryptData(keyPair.publicKey, originalData);
console.log("Encrypted:", new Uint8Array(encrypted));
// 解密
const decrypted = await decryptData(keyPair.privateKey, encrypted);
console.log("Decrypted:", decrypted);
}
注意事项
Web Crypto API只能在安全上下文(HTTPS或localhost)中使用。对于Node.js环境,可以使用crypto模块:
const crypto = require('crypto');
function nodeRsaEncrypt(publicKey, data) {
return crypto.publicEncrypt(
{
key: publicKey,
padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
oaepHash: 'sha256'
},
Buffer.from(data)
);
}
密钥格式处理
实际应用中可能需要处理PEM格式的密钥:

// 从PEM字符串导入公钥
async function importPublicKey(pem) {
const pemHeader = "-----BEGIN PUBLIC KEY-----";
const pemFooter = "-----END PUBLIC KEY-----";
const pemContents = pem.substring(
pemHeader.length,
pem.length - pemFooter.length
);
const binaryDer = atob(pemContents);
return await window.crypto.subtle.importKey(
"spki",
str2ab(binaryDer),
{ name: "RSA-OAEP", hash: "SHA-256" },
true,
["encrypt"]
);
}
// 字符串转ArrayBuffer
function str2ab(str) {
const buf = new ArrayBuffer(str.length);
const bufView = new Uint8Array(buf);
for (let i = 0; i < str.length; i++) {
bufView[i] = str.charCodeAt(i);
}
return buf;
}
性能考虑
RSA加密适合加密少量数据(如加密对称密钥)。对于大量数据,建议使用RSA加密对称密钥,再用对称密钥加密数据。






