import crypto from 'crypto';
const deriveKey = (secret: string): Buffer => {
return crypto.createHash('sha256').update(secret).digest();
};
export const encryptSecret = (plaintext: string, secret: string): string => {
const key = deriveKey(secret);
const iv = crypto.randomBytes(12);
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);
const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
const tag = cipher.getAuthTag();
return [iv.toString('base64'), tag.toString('base64'), encrypted.toString('base64')].join(':');
};
export const decryptSecret = (payload: string, secret: string): string => {
const [ivB64, tagB64, dataB64] = payload.split(':');
if (!ivB64 || !tagB64 || !dataB64) {
throw new Error('Invalid encrypted payload format');
}
const key = deriveKey(secret);
const iv = Buffer.from(ivB64, 'base64');
const tag = Buffer.from(tagB64, 'base64');
const data = Buffer.from(dataB64, 'base64');
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
decipher.setAuthTag(tag);
const decrypted = Buffer.concat([decipher.update(data), decipher.final()]);
return decrypted.toString('utf8');
};
export const hashKey = (value: string): string => {
return crypto.createHash('sha256').update(value).digest('hex');
};
export const maskKey = (value: string): string => {
if (!value) return '';
if (value.length <= 10) return `${value.slice(0, 3)}...${value.slice(-2)}`;
return `${value.slice(0, 6)}...${value.slice(-4)}`;
};