64 lines
2.3 KiB
JavaScript
64 lines
2.3 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.initEncryption = initEncryption;
|
|
exports.encrypt = encrypt;
|
|
exports.decrypt = decrypt;
|
|
exports.isEncrypted = isEncrypted;
|
|
const crypto_1 = require("crypto");
|
|
const ALGORITHM = 'aes-256-gcm';
|
|
const IV_LENGTH = 12;
|
|
const AUTH_TAG_LENGTH = 16;
|
|
const PREFIX = 'enc:';
|
|
/** Derive a 32-byte key from an arbitrary-length secret */
|
|
function deriveKey(secret) {
|
|
return (0, crypto_1.createHash)('sha256').update(secret).digest();
|
|
}
|
|
let _key = null;
|
|
/** Initialize (or re-initialize) the encryption key. Call once at startup. */
|
|
function initEncryption(secret) {
|
|
_key = deriveKey(secret);
|
|
}
|
|
function getKey() {
|
|
if (!_key) {
|
|
throw new Error('Encryption not initialized — call initEncryption() first');
|
|
}
|
|
return _key;
|
|
}
|
|
/**
|
|
* Encrypt a plaintext string.
|
|
* Returns format: `enc:<iv>:<authTag>:<ciphertext>` (all base64).
|
|
*/
|
|
function encrypt(plaintext) {
|
|
if (!plaintext)
|
|
return plaintext;
|
|
const key = getKey();
|
|
const iv = (0, crypto_1.randomBytes)(IV_LENGTH);
|
|
const cipher = (0, crypto_1.createCipheriv)(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
const authTag = cipher.getAuthTag();
|
|
return `${PREFIX}${iv.toString('base64')}:${authTag.toString('base64')}:${encrypted.toString('base64')}`;
|
|
}
|
|
/**
|
|
* Decrypt a value produced by encrypt().
|
|
* If the value doesn't have the `enc:` prefix, returns it as-is (backward compat for plaintext).
|
|
*/
|
|
function decrypt(value) {
|
|
if (!value || !value.startsWith(PREFIX))
|
|
return value;
|
|
const key = getKey();
|
|
const parts = value.slice(PREFIX.length).split(':');
|
|
if (parts.length !== 3)
|
|
return value;
|
|
const iv = Buffer.from(parts[0], 'base64');
|
|
const authTag = Buffer.from(parts[1], 'base64');
|
|
const ciphertext = Buffer.from(parts[2], 'base64');
|
|
const decipher = (0, crypto_1.createDecipheriv)(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
decipher.setAuthTag(authTag);
|
|
const decrypted = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
return decrypted.toString('utf8');
|
|
}
|
|
/** Check whether a value is already encrypted */
|
|
function isEncrypted(value) {
|
|
return !!value && value.startsWith(PREFIX);
|
|
}
|
|
//# sourceMappingURL=crypto.js.map
|