feat: add web AES-256-GCM secret crypto and LYRA_SECRET_KEY plumbing
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import { createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
|
||||
|
||||
function key(): Buffer {
|
||||
const b64 = process.env.LYRA_SECRET_KEY;
|
||||
if (!b64) throw new Error("LYRA_SECRET_KEY is not set");
|
||||
const k = Buffer.from(b64, "base64");
|
||||
if (k.length !== 32) throw new Error("LYRA_SECRET_KEY must decode to 32 bytes");
|
||||
return k;
|
||||
}
|
||||
|
||||
export function encryptSecret(plaintext: string): string {
|
||||
const iv = randomBytes(12);
|
||||
const cipher = createCipheriv("aes-256-gcm", key(), iv);
|
||||
const ct = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
||||
const tag = cipher.getAuthTag();
|
||||
return JSON.stringify({
|
||||
iv: iv.toString("base64"),
|
||||
ct: ct.toString("base64"),
|
||||
tag: tag.toString("base64"),
|
||||
});
|
||||
}
|
||||
|
||||
export function decryptSecret(envelope: string): string {
|
||||
const { iv, ct, tag } = JSON.parse(envelope) as { iv: string; ct: string; tag: string };
|
||||
const decipher = createDecipheriv("aes-256-gcm", key(), Buffer.from(iv, "base64"));
|
||||
decipher.setAuthTag(Buffer.from(tag, "base64"));
|
||||
const pt = Buffer.concat([decipher.update(Buffer.from(ct, "base64")), decipher.final()]);
|
||||
return pt.toString("utf8");
|
||||
}
|
||||
Reference in New Issue
Block a user