-
Matiss Janis Aboltins authoredMatiss Janis Aboltins authored
encryption-internals.ts 2.14 KiB
// @ts-strict-ignore
import crypto from 'crypto';
const ENCRYPTION_ALGORITHM = 'aes-256-gcm' as const;
export async function sha256String(str) {
return crypto.createHash('sha256').update(str).digest('base64');
}
export function randomBytes(n) {
return crypto.randomBytes(n);
}
export function encrypt(masterKey, value) {
const masterKeyBuffer = masterKey.getValue().raw;
// let iv = createKeyBuffer({ numBytes: 12, secret: masterKeyBuffer });
const iv = crypto.randomBytes(12);
const cipher = crypto.createCipheriv(
ENCRYPTION_ALGORITHM,
masterKeyBuffer,
iv,
);
let encrypted = cipher.update(value);
encrypted = Buffer.concat([encrypted, cipher.final()]);
const authTag = cipher.getAuthTag();
return {
value: encrypted,
meta: {
keyId: masterKey.getId(),
algorithm: ENCRYPTION_ALGORITHM,
iv: iv.toString('base64'),
authTag: authTag.toString('base64'),
},
};
}
export function decrypt(masterKey, encrypted, meta) {
const masterKeyBuffer = masterKey.getValue().raw;
const { algorithm, iv: originalIv, authTag: originalAuthTag } = meta;
const iv = Buffer.from(originalIv, 'base64');
const authTag = Buffer.from(originalAuthTag, 'base64');
const decipher = crypto.createDecipheriv(algorithm, masterKeyBuffer, iv);
decipher.setAuthTag(authTag);
let decrypted = decipher.update(encrypted);
decrypted = Buffer.concat([decrypted, decipher.final()]);
return decrypted;
}
export function createKey({ secret, salt }) {
const buffer = createKeyBuffer({ secret, salt });
return {
raw: buffer,
base64: buffer.toString('base64'),
};
}
export function importKey(str) {
return {
raw: Buffer.from(str, 'base64'),
base64: str,
};
}
/**
* Generates a Buffer of a desired byte length to be used as either an encryption key or an initialization vector.
*
* @private
*/
function createKeyBuffer({
numBytes,
secret,
salt,
}: {
numBytes?: number;
secret?: string;
salt?: string;
}) {
return crypto.pbkdf2Sync(
secret || crypto.randomBytes(128).toString('base64'),
salt || crypto.randomBytes(32).toString('base64'),
10000,
numBytes || 32,
'sha512',
);
}