52 lines
1.8 KiB
TypeScript
52 lines
1.8 KiB
TypeScript
import crypto from "node:crypto";
|
|
|
|
// Key derivation from password
|
|
const algorithm = "aes-256-gcm";
|
|
// TODO: make salt vary by use case;
|
|
const salt = "saltysalt";
|
|
|
|
export const encrypt = (props: { password: string; text: string }) => {
|
|
const { password, text } = props;
|
|
const key = new Uint8Array(crypto.scryptSync(password, salt, 32)); // 32 bytes key
|
|
const iv = new Uint8Array(crypto.randomBytes(16)); // Initialization Vector
|
|
// Encryption
|
|
const cipher = crypto.createCipheriv(algorithm, key, iv);
|
|
let encrypted = cipher.update(text, "utf8", "hex");
|
|
encrypted += cipher.final("hex");
|
|
const authTag = cipher.getAuthTag().toString("hex");
|
|
const fullEncrypted =
|
|
authTag + "+" + Buffer.from(iv).toString("hex") + ":" + encrypted; // Store IV with encrypted data
|
|
// console.log({ iv, authTag });
|
|
return fullEncrypted;
|
|
};
|
|
|
|
export const decrypt = (props: { password: string; cyphertext: string }) => {
|
|
const { password, cyphertext } = props;
|
|
const key = new Uint8Array(crypto.scryptSync(password, salt, 32)); // 32 bytes key
|
|
// Decryption
|
|
const [pre, encryptedHex] = cyphertext.split(":");
|
|
const [authTag, ivHex] = pre.split("+");
|
|
const ivFromStorage = new Uint8Array(Buffer.from(ivHex, "hex"));
|
|
// console.log({ ivFromStorage, authTag });
|
|
const decipher = crypto.createDecipheriv(algorithm, key, ivFromStorage);
|
|
decipher.setAuthTag(new Uint8Array(Buffer.from(authTag, "hex")));
|
|
let decrypted = decipher.update(encryptedHex, "hex", "utf8");
|
|
decrypted += decipher.final("utf8");
|
|
return decrypted;
|
|
};
|
|
|
|
// console.log(process.env.ENCRYPTION_PASSWORD);
|
|
|
|
// const x = encrypt({
|
|
// password: process.env.ENCRYPTION_PASSWORD!,
|
|
// text: "",
|
|
// });
|
|
|
|
// const y = decrypt({
|
|
// password: process.env.ENCRYPTION_PASSWORD!,
|
|
// cyphertext: "",
|
|
// });
|
|
|
|
// console.log(x);
|
|
// console.log(y);
|