23 lines
943 B
TypeScript
23 lines
943 B
TypeScript
/** AES-256-GCM for merchant messaging credentials. APP_ENCRYPTION_KEY = 32 random bytes, base64. */
|
|
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
|
|
|
function key(): Buffer {
|
|
const k = Buffer.from(process.env.APP_ENCRYPTION_KEY ?? "", "base64");
|
|
if (k.length !== 32) throw new Error("APP_ENCRYPTION_KEY must be 32 bytes (base64)");
|
|
return k;
|
|
}
|
|
|
|
export function encrypt(plain: string): string {
|
|
const iv = randomBytes(12);
|
|
const c = createCipheriv("aes-256-gcm", key(), iv);
|
|
const enc = Buffer.concat([c.update(plain, "utf8"), c.final()]);
|
|
return [iv, c.getAuthTag(), enc].map((b) => b.toString("base64url")).join(".");
|
|
}
|
|
|
|
export function decrypt(blob: string): string {
|
|
const [iv, tag, enc] = blob.split(".").map((p) => Buffer.from(p, "base64url"));
|
|
const d = createDecipheriv("aes-256-gcm", key(), iv);
|
|
d.setAuthTag(tag);
|
|
return Buffer.concat([d.update(enc), d.final()]).toString("utf8");
|
|
}
|