UNPKG

kaven-utils

Version:

Utils for Node.js.

121 lines (120 loc) 5.19 kB
/******************************************************************** * @author: Kaven * @email: kaven@wuwenkai.com * @website: http://blog.kaven.xyz * @file: [Kaven-Utils] /src/KavenRSA.ts * @create: 2020-07-10 13:39:53.988 * @modify: 2024-11-01 10:48:07.329 * @version: 5.4.5 * @times: 29 * @lines: 232 * @copyright: Copyright © 2020-2024 Kaven. All Rights Reserved. * @description: [description] * @license: [license] ********************************************************************/ import { constants, createVerify, generateKeyPairSync, privateDecrypt, publicEncrypt, sign } from "node:crypto"; import { String2StringArray, StringArray2String } from "kaven-basic"; import { DecryptString, EncryptString, GenerateEncryptPassword } from "./KavenUtility.Crypto.js"; /** * crypto wrap * @since 2.0.8 * @version 2020-07-10 */ export class KavenRSA { PublicKey; PrivateKey; constructor(publicKey, privateKey) { this.PublicKey = publicKey; this.PrivateKey = privateKey; } static Create(bits = 4096, exponent = 65537) { const keys = generateKeyPairSync("rsa", { modulusLength: bits, publicExponent: exponent, }); const publicKey = keys.publicKey.export({ type: "pkcs1", format: "pem", }).toString(); const privateKey = keys.privateKey.export({ type: "pkcs8", format: "pem", }).toString(); return new KavenRSA(publicKey, privateKey); } // #region Core Methods Encrypt(data, padding = constants.RSA_PKCS1_OAEP_PADDING, oaepHash = "sha256") { if (this.PublicKey === undefined) { throw new Error("publicKey is undefined"); } return publicEncrypt({ key: this.PublicKey, padding, oaepHash, }, data); } Decrypt(data, padding = constants.RSA_PKCS1_OAEP_PADDING, oaepHash = "sha256") { if (this.PrivateKey === undefined) { throw new Error("privateKey is undefined"); } return privateDecrypt({ key: this.PrivateKey, padding, oaepHash, }, data); } Sign(data, algorithm = "sha256", padding = constants.RSA_PKCS1_PSS_PADDING, saltLength = constants.RSA_PSS_SALTLEN_DIGEST) { if (this.PrivateKey === undefined) { throw new Error("privateKey is undefined"); } return sign(algorithm, data, { key: this.PrivateKey, padding, saltLength, }); } Verify(data, signature, algorithm = "sha256", padding = constants.RSA_PKCS1_PSS_PADDING, saltLength = constants.RSA_PSS_SALTLEN_DIGEST) { if (this.PublicKey === undefined) { throw new Error("publicKey is undefined"); } const verify = createVerify(algorithm); verify.update(data); return verify.verify({ key: this.PublicKey, padding, saltLength, }, signature); } // #endregion // #region Helper Methods EncryptToString(data, encoding = "base64", padding = constants.RSA_PKCS1_OAEP_PADDING, oaepHash = "sha256") { return this.Encrypt(Buffer.from(JSON.stringify(data)), padding, oaepHash).toString(encoding); } DecryptFromString(data, encoding = "base64", padding = constants.RSA_PKCS1_OAEP_PADDING, oaepHash = "sha256") { return JSON.parse(this.Decrypt(Buffer.from(data, encoding), padding, oaepHash).toString()); } SignToString(data, encoding = "base64", algorithm = "sha256", padding = constants.RSA_PKCS1_PSS_PADDING, saltLength = constants.RSA_PSS_SALTLEN_DIGEST) { return this.Sign(Buffer.from(JSON.stringify(data)), algorithm, padding, saltLength).toString(encoding); } VerifyFromString(data, signature, encoding = "base64", algorithm = "sha256", padding = constants.RSA_PKCS1_PSS_PADDING, saltLength = constants.RSA_PSS_SALTLEN_DIGEST) { return this.Verify(Buffer.from(JSON.stringify(data)), Buffer.from(signature, encoding), algorithm, padding, saltLength); } EncryptBigData(data, encoding = "base64", padding = constants.RSA_PKCS1_OAEP_PADDING, oaepHash = "sha256") { const password = GenerateEncryptPassword(); const dataStr = JSON.stringify(data); const encryptedData = EncryptString(dataStr, password); const encryptedPassword = this.EncryptToString(password, encoding, padding, oaepHash); return StringArray2String(encryptedData, encryptedPassword); } DecryptBigData(data, encoding = "base64", padding = constants.RSA_PKCS1_OAEP_PADDING, oaepHash = "sha256") { const items = String2StringArray(data); if (items && items.length === 2) { const encryptedData = items[0]; const encryptedPassword = items[1]; const password = this.DecryptFromString(encryptedPassword, encoding, padding, oaepHash); const dataStr = DecryptString(encryptedData, password); return JSON.parse(dataStr); } throw new Error("DecryptBigData failed"); } }