protoobject
Version:
A universal class for creating any JSON objects and simple manipulations with them.
129 lines • 4.28 kB
JavaScript
/**
* ProtoObjectCrypto - Cryptographic utilities for ProtoObject
* @description Provides encryption, hashing, and digital signature capabilities
* @author Siarhei Dudko <siarhei@dudko.dev>
*/
import { createHash, createCipheriv, createDecipheriv, randomBytes, } from "node:crypto";
import { ProtoObject } from "./proto-object.js";
/* eslint-disable no-unused-vars */
/**
* Encryption algorithms supported
*/
export var EncryptionAlgorithm;
(function (EncryptionAlgorithm) {
EncryptionAlgorithm["AES256"] = "aes-256-cbc";
EncryptionAlgorithm["AES192"] = "aes-192-cbc";
EncryptionAlgorithm["AES128"] = "aes-128-cbc";
})(EncryptionAlgorithm || (EncryptionAlgorithm = {}));
/**
* Hash algorithms supported
*/
export var HashAlgorithm;
(function (HashAlgorithm) {
HashAlgorithm["SHA256"] = "sha256";
HashAlgorithm["SHA512"] = "sha512";
HashAlgorithm["MD5"] = "md5";
})(HashAlgorithm || (HashAlgorithm = {}));
/* eslint-enable no-unused-vars */
/**
* Base class for Crypto-enabled ProtoObjects
*/
export class ProtoObjectCrypto extends ProtoObject {
constructor(data) {
super(data);
}
/**
* Generate hash of the object
* @param algorithm - Hash algorithm to use
* @returns Hash string
*/
generateHash(algorithm = HashAlgorithm.SHA256) {
const data = JSON.stringify(this.toJSON());
const hash = createHash(algorithm).update(data).digest("hex");
this._hash = hash;
return hash;
}
/**
* Get stored hash
* @returns Hash string or undefined
*/
getHash() {
return this._hash;
}
/**
* Encrypt object data
* @param password - Encryption password
* @param algorithm - Encryption algorithm
* @returns Encrypted data structure
*/
encrypt(password, algorithm = EncryptionAlgorithm.AES256) {
const data = JSON.stringify(this.toJSON());
const salt = randomBytes(16);
const iv = randomBytes(16);
// Derive key from password and salt
const key = createHash("sha256")
.update(password + salt.toString("hex"))
.digest();
const cipher = createCipheriv(algorithm, key, iv);
let encrypted = cipher.update(data, "utf8", "hex");
encrypted += cipher.final("hex");
return {
algorithm,
data: encrypted,
iv: iv.toString("hex"),
salt: salt.toString("hex"),
};
}
/**
* Decrypt encrypted data
* @param encryptedData - Encrypted data structure
* @param password - Decryption password
* @returns Decrypted object data
*/
static decrypt(encryptedData, password) {
const { algorithm, data, iv, salt } = encryptedData;
// Derive key from password and salt
const key = createHash("sha256")
.update(password + salt)
.digest();
const decipher = createDecipheriv(algorithm, key, Buffer.from(iv, "hex"));
let decrypted = decipher.update(data, "hex", "utf8");
decrypted += decipher.final("utf8");
return JSON.parse(decrypted);
}
/**
* Generate random salt for encryption
* @param length - Salt length in bytes
* @returns Hex string salt
*/
static generateSalt(length = 16) {
return randomBytes(length).toString("hex");
}
/**
* Verify hash of the object
* @param expectedHash - Expected hash value
* @param algorithm - Hash algorithm used
* @returns True if hash matches
*/
verifyHash(expectedHash, algorithm = HashAlgorithm.SHA256) {
const currentHash = this.generateHash(algorithm);
return currentHash === expectedHash;
}
/**
* Create encrypted backup of the object
* @param password - Encryption password
* @param algorithm - Encryption algorithm
* @returns Encrypted backup data
*/
createEncryptedBackup(password, algorithm = EncryptionAlgorithm.AES256) {
const hash = this.generateHash();
const encrypted = this.encrypt(password, algorithm);
return {
hash,
encrypted,
timestamp: Date.now(),
algorithm,
};
}
}
//# sourceMappingURL=proto-object-crypto.js.map