有些登录场景需要使用非对称加密来保证密码安全传输,其实使用https的话,密码已经很安全了。

crypto 非对称加密

17:25 · 2025年12月22日 · 周一 show: --

使用node自带模块crypto实现rsa非对称加密。

有些登录场景需要使用非对称加密来保证密码安全传输,其实使用https的话,密码已经很安全了。

直接上代码

1. 遇到一些坑,字符串转换的时候得区分什么时候要base64,什么时候要utf8的

import crypto from 'crypto';

let publicKey;
let privateKey;
/** 生成密钥 */
export function generateRSAKeyPair() {
    const data = crypto.generateKeyPairSync('rsa', {
        modulusLength: 2048,
        publicKeyEncoding: { type: 'spki', format: 'pem' },
        privateKeyEncoding: { type: 'pkcs8', format: 'pem' },
    });
    publicKey = data.publicKey;
    privateKey = data.privateKey;
}
export function getPublicKey() {
    return publicKey;
}
/** 公钥加密 */
export function publicEncrypt(data) {
    const encryptedData = crypto.publicEncrypt(
        {
            key: publicKey,
            padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
            oaepHash: 'sha256',
        },
        Buffer.from(data, 'utf8')
    );
    return encryptedData.toString('base64');
}
/** 私钥解密 */
export function privateDecrypt(encryptedData) {
    encryptedData = Buffer.from(encryptedData, 'base64');
    const decryptedData = crypto.privateDecrypt(
        {
            key: privateKey,
            padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,
            oaepHash: 'sha256',
        },
        encryptedData
    );
    return decryptedData.toString('utf8');
}

调用的时候

import { generateRSAKeyPair, publicEncrypt, privateDecrypt } from './rsa-tools.js';

async function test() {
    generateRSAKeyPair();
    const data = publicEncrypt('123asdjk 看哈是的话123asdjk123asdjk123asdjk123asdjk123asdjk123asdjk');
    console.log('en: ', data);
    console.log('de: ', privateDecrypt(data));
}
test();

2. 前后端通用的话可以试试这种

import NodeRSA from 'node-rsa';

let publicKey = ``;
let privateKey = ``;
let key;
/** 生成密钥 */
export function generateRSAKeyPair() {
    key = new NodeRSA({ b: 512 });
    publicKey = key.exportKey('pkcs8-public');
    privateKey = key.exportKey('pkcs8-private');
}
export function getPublicKey() {
    return publicKey;
}
/** 公钥加密 */
export function publicEncrypt(data) {
    return key.encrypt(data, 'base64');
}
/** 私钥解密 */
export function privateDecrypt(encryptedData) {
    return key.decrypt(encryptedData, 'utf8');
}

3. 前后端通用

import forge from 'node-forge';

let publicKey = ``;
let privateKey = ``;
let key;
/** 生成密钥 */
export function generateRSAKeyPair() {
    key = forge.pki.rsa.generateKeyPair(2048);
    publicKey = forge.pki.publicKeyToPem(key.publicKey);
    privateKey = forge.pki.privateKeyToPem(key.privateKey);
}
export function getPublicKey() {
    return publicKey;
}
/** 公钥加密 */
export function publicEncrypt(plainText) {
    try {
        const plainTextBytes = forge.util.encodeUtf8(plainText);
        const encryptedBytes = key.publicKey.encrypt(plainTextBytes, 'RSA-OAEP', {
            md: forge.md.sha256.create(),
            mgf1: { md: forge.md.sha256.create() },
        });
        return forge.util.encode64(encryptedBytes);
    } catch (error) {
        throw new Error(`加密失败:${error.message}`);
    }
}
/** 私钥解密 */
export function privateDecrypt(encryptedBase64) {
    try {
        const encryptedBytes = forge.util.decode64(encryptedBase64);
        const decryptedBytes = key.privateKey.decrypt(encryptedBytes, 'RSA-OAEP', {
            md: forge.md.sha256.create(),
            mgf1: { md: forge.md.sha256.create() },
        });
        return forge.util.decodeUtf8(decryptedBytes);
    } catch (error) {
        throw new Error(`解密失败:${error.message}`);
    }
}
最后一次更新时间: 17:25 · 2025年12月22日 · 周一