UNPKG

protoobject

Version:

A universal class for creating any JSON objects and simple manipulations with them.

133 lines (132 loc) 4.61 kB
"use strict"; /** * ProtoObjectCrypto - Cryptographic utilities for ProtoObject * @description Provides encryption, hashing, and digital signature capabilities * @author Siarhei Dudko <siarhei@dudko.dev> */ Object.defineProperty(exports, "__esModule", { value: true }); exports.ProtoObjectCrypto = exports.HashAlgorithm = exports.EncryptionAlgorithm = void 0; const node_crypto_1 = require("node:crypto"); const proto_object_js_1 = require("./proto-object.js"); /* eslint-disable no-unused-vars */ /** * Encryption algorithms supported */ var EncryptionAlgorithm; (function (EncryptionAlgorithm) { EncryptionAlgorithm["AES256"] = "aes-256-cbc"; EncryptionAlgorithm["AES192"] = "aes-192-cbc"; EncryptionAlgorithm["AES128"] = "aes-128-cbc"; })(EncryptionAlgorithm || (exports.EncryptionAlgorithm = EncryptionAlgorithm = {})); /** * Hash algorithms supported */ var HashAlgorithm; (function (HashAlgorithm) { HashAlgorithm["SHA256"] = "sha256"; HashAlgorithm["SHA512"] = "sha512"; HashAlgorithm["MD5"] = "md5"; })(HashAlgorithm || (exports.HashAlgorithm = HashAlgorithm = {})); /* eslint-enable no-unused-vars */ /** * Base class for Crypto-enabled ProtoObjects */ class ProtoObjectCrypto extends proto_object_js_1.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 = (0, node_crypto_1.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 = (0, node_crypto_1.randomBytes)(16); const iv = (0, node_crypto_1.randomBytes)(16); // Derive key from password and salt const key = (0, node_crypto_1.createHash)("sha256") .update(password + salt.toString("hex")) .digest(); const cipher = (0, node_crypto_1.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 = (0, node_crypto_1.createHash)("sha256") .update(password + salt) .digest(); const decipher = (0, node_crypto_1.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 (0, node_crypto_1.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, }; } } exports.ProtoObjectCrypto = ProtoObjectCrypto;