import BaseService from "@Services/BaseService"; import { Service } from "typedi"; import { BackendVariables } from "@Common/config/variables/Variables"; import crypto from "crypto"; @Service() export default class CryptoService extends BaseService { private static readonly CRYPTO_ALGORITHM = "aes-256-ctr"; constructor(protected variables: BackendVariables) { super(); } private getKey(key: string) { return crypto.createHash('sha256').update(String(key)).digest('base64').slice(0, 32); } /** * @description : encrypt data * @throws {Error} If data cannot be encrypted */ public async encrypt(buffer: Buffer, key: string): Promise { // Create an initialization vector const iv = crypto.randomBytes(16); // Create a new cipher using the algorithm, key, and iv const cipher = crypto.createCipheriv(CryptoService.CRYPTO_ALGORITHM, this.getKey(key), iv); // Create the new (encrypted) buffer const result = Buffer.concat([iv, cipher.update(buffer), cipher.final()]); return result; } /** * @description : decrypt data with an initialization vector * @throws {Error} If data cannot be decrypted */ public async decrypt(encrypted: Buffer, key: string): Promise { // Get the iv: the first 16 bytes const iv = encrypted.subarray(0, 16); // Get the rest encrypted = encrypted.subarray(16); // Create a decipher const decipher = crypto.createDecipheriv(CryptoService.CRYPTO_ALGORITHM, this.getKey(key), iv); // Actually decrypt it const result = Buffer.concat([decipher.update(encrypted), decipher.final()]); return result; } }