import crypto from 'crypto'; function getHmacSecret(): string { const secret = process.env.API_KEY_HMAC_SECRET; if (!secret) { throw new Error( 'API_KEY_HMAC_SECRET environment variable is required for API key hashing. ' + 'Generate with: openssl rand -hex 32' ); } return secret; } export function hashApiKey(raw: string): string { return crypto .createHmac('sha256', getHmacSecret()) .update(raw) .digest('hex'); } export function verifyApiKey(raw: string, hash: string): boolean { const expected = hashApiKey(raw); if (expected.length !== hash.length) return false; return crypto.timingSafeEqual( Buffer.from(expected, 'hex'), Buffer.from(hash, 'hex') ); } export function legacySha256Hash(raw: string): string { return crypto.createHash('sha256').update(raw).digest('hex'); }