diff --git a/backend/utils/crypto.js b/backend/utils/crypto.js index 7456d0c..ef10b7d 100644 --- a/backend/utils/crypto.js +++ b/backend/utils/crypto.js @@ -21,10 +21,10 @@ function getPublicKey() { function decryptPayload(encryptedAesKeyBase64, encryptedDataBase64) { if (!privateKey) throw new Error('Keys not initialized'); - // 1. RSA 解密 AES 密钥 + // 1. RSA 解密 AES 密钥 (使用 OAEP) const encryptedAesKeyBuffer = Buffer.from(encryptedAesKeyBase64, 'base64'); const aesKeyStr = crypto.privateDecrypt( - { key: privateKey, padding: crypto.constants.RSA_PKCS1_PADDING }, + { key: privateKey, padding: crypto.constants.RSA_PKCS1_OAEP_PADDING }, encryptedAesKeyBuffer ).toString('utf8'); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 77609dc..e960356 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -14,6 +14,7 @@ "crypto-js": "^4.2.0", "element-plus": "^2.3.14", "jsencrypt": "^3.5.4", + "node-forge": "^1.3.3", "pinia": "^2.1.7", "socket.io-client": "^4.7.5", "vue": "^3.3.4", @@ -1261,6 +1262,15 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, + "node_modules/node-forge": { + "version": "1.3.3", + "resolved": "https://registry.npmmirror.com/node-forge/-/node-forge-1.3.3.tgz", + "integrity": "sha512-rLvcdSyRCyouf6jcOIPe/BgwG/d7hKjzMKOas33/pHEr6gbq18IK9zV7DiPvzsz0oBJPme6qr6H6kGZuI9/DZg==", + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, "node_modules/normalize-wheel-es": { "version": "1.2.0", "resolved": "https://registry.npmmirror.com/normalize-wheel-es/-/normalize-wheel-es-1.2.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index d773b0a..c6bbce0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -14,6 +14,7 @@ "crypto-js": "^4.2.0", "element-plus": "^2.3.14", "jsencrypt": "^3.5.4", + "node-forge": "^1.3.3", "pinia": "^2.1.7", "socket.io-client": "^4.7.5", "vue": "^3.3.4", diff --git a/frontend/src/utils/crypto.js b/frontend/src/utils/crypto.js index f754076..0908ce1 100644 --- a/frontend/src/utils/crypto.js +++ b/frontend/src/utils/crypto.js @@ -1,5 +1,5 @@ import axios from 'axios'; -import JSEncrypt from 'jsencrypt'; +import forge from 'node-forge'; import CryptoJS from 'crypto-js'; let publicKeyCache = null; @@ -39,11 +39,19 @@ export async function encryptPayload(data) { padding: CryptoJS.pad.Pkcs7 }).toString(); // 自动输出 base64 - // 3. 使用 RSA 加密 AES 密钥和 IV - const encryptor = new JSEncrypt(); - encryptor.setPublicKey(pubKey); + // 3. 使用 RSA-OAEP 加密 AES 密钥和 IV + const publicKeyObj = forge.pki.publicKeyFromPem(pubKey); const sessionKeyObj = JSON.stringify({ key: aesKeyStr, iv: ivStr }); - const encryptedKey = encryptor.encrypt(sessionKeyObj); + + // forge 的 encrypt 默认使用 RSAES-PKCS1-V1_5,若需要 OAEP: + const encryptedKeyBytes = publicKeyObj.encrypt(sessionKeyObj, 'RSA-OAEP', { + md: forge.md.sha1.create(), + mgf1: { + md: forge.md.sha1.create() + } + }); + + const encryptedKey = forge.util.encode64(encryptedKeyBytes); if (!encryptedKey) { throw new Error('RSA 加密失败,可能是数据过长或公钥无效');