38 lines
1.4 KiB
TypeScript
38 lines
1.4 KiB
TypeScript
import { createCipheriv, createDecipheriv, randomBytes, createHash } from 'node:crypto';
|
|
import { config } from '../config.js';
|
|
|
|
const ALGORITHM = 'aes-256-gcm';
|
|
const IV_LENGTH = 12;
|
|
const AUTH_TAG_LENGTH = 16;
|
|
|
|
function getKey(): Buffer {
|
|
return Buffer.from(config.tokenEncryptionKey, 'hex');
|
|
}
|
|
|
|
export function encrypt(plaintext: string): { ciphertext: string; iv: string } {
|
|
const key = getKey();
|
|
const iv = randomBytes(IV_LENGTH);
|
|
const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
const authTag = cipher.getAuthTag();
|
|
return {
|
|
ciphertext: Buffer.concat([encrypted, authTag]).toString('base64'),
|
|
iv: iv.toString('base64'),
|
|
};
|
|
}
|
|
|
|
export function decrypt(ciphertext: string, iv: string): string {
|
|
const key = getKey();
|
|
const ivBuf = Buffer.from(iv, 'base64');
|
|
const data = Buffer.from(ciphertext, 'base64');
|
|
const authTag = data.subarray(data.length - AUTH_TAG_LENGTH);
|
|
const encrypted = data.subarray(0, data.length - AUTH_TAG_LENGTH);
|
|
const decipher = createDecipheriv(ALGORITHM, key, ivBuf, { authTagLength: AUTH_TAG_LENGTH });
|
|
decipher.setAuthTag(authTag);
|
|
return decipher.update(encrypted) + decipher.final('utf8');
|
|
}
|
|
|
|
export function hashToken(token: string): string {
|
|
return createHash('sha256').update(token).digest('hex');
|
|
}
|