diff --git a/.env.example b/.env.example index ab39bf3..6e7b983 100644 --- a/.env.example +++ b/.env.example @@ -1,5 +1,6 @@ APP_BASE_URL=http://localhost:3000 - +# crypto.scryptSync("je s'appelle groot", crypto.randomBytes(16), 32).toString("hex"); +MASTER_ENCRYPTION_KEY=97da37a1003158d7da3d8c10186e61423fd7fa56a4565e3ba4f093b8343780a9 INVITATION_TOKEN_SECRET=0ded075524fd19fe467eb00480b8d5d4 SESSION_SECRET=754a554f4cbf9254e50fda87b48ee52b diff --git a/app/config/config.server.ts b/app/config/config.server.ts index 3aa3751..11d1a15 100644 --- a/app/config/config.server.ts +++ b/app/config/config.server.ts @@ -20,13 +20,21 @@ invariant( `Please define the "AWS_SES_FROM_EMAIL" environment variable`, ); invariant(typeof process.env.REDIS_URL === "string", `Please define the "REDIS_URL" environment variable`); -invariant(typeof process.env.TWILIO_AUTH_TOKEN === "string", `Please define the "TWILIO_AUTH_TOKEN" environment variable`); +invariant( + typeof process.env.TWILIO_AUTH_TOKEN === "string", + `Please define the "TWILIO_AUTH_TOKEN" environment variable`, +); +invariant( + typeof process.env.MASTER_ENCRYPTION_KEY === "string", + `Please define the "MASTER_ENCRYPTION_KEY" environment variable`, +); export default { app: { baseUrl: process.env.APP_BASE_URL, invitationTokenSecret: process.env.INVITATION_TOKEN_SECRET, sessionSecret: process.env.SESSION_SECRET, + encryptionKey: process.env.MASTER_ENCRYPTION_KEY, }, awsSes: { awsRegion: process.env.AWS_SES_REGION, diff --git a/app/utils/encryption.ts b/app/utils/encryption.ts new file mode 100644 index 0000000..6852e0d --- /dev/null +++ b/app/utils/encryption.ts @@ -0,0 +1,29 @@ +import crypto from "crypto"; + +import serverConfig from "~/config/config.server"; + +const ivLength = 16; +const algorithm = "aes-256-cbc"; +const encryptionKey = serverConfig.app.encryptionKey; + +export function encrypt(text: string) { + const encryptionKeyAsBuffer = Buffer.isBuffer(encryptionKey) ? encryptionKey : Buffer.from(encryptionKey, "hex"); + const iv = crypto.randomBytes(ivLength); + const cipher = crypto.createCipheriv(algorithm, encryptionKeyAsBuffer, iv); + const encrypted = cipher.update(text); + const encryptedBuffer = Buffer.concat([encrypted, cipher.final()]); + + return `${iv.toString("hex")}:${encryptedBuffer.toString("hex")}`; +} + +export function decrypt(encryptedHexText: string) { + const encryptionKeyAsBuffer = Buffer.isBuffer(encryptionKey) ? encryptionKey : Buffer.from(encryptionKey, "hex"); + const [hexIv, hexText] = encryptedHexText.split(":"); + const iv = Buffer.from(hexIv!, "hex"); + const encryptedText = Buffer.from(hexText!, "hex"); + const decipher = crypto.createDecipheriv(algorithm, encryptionKeyAsBuffer, iv); + const decrypted = decipher.update(encryptedText); + const decryptedBuffer = Buffer.concat([decrypted, decipher.final()]); + + return decryptedBuffer.toString(); +}