kaven-utils
Version:
Utils for Node.js.
121 lines (120 loc) • 5.19 kB
JavaScript
/********************************************************************
* @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");
}
}