1
0
Fork 0
mirror of synced 2024-08-16 18:41:37 +12:00

Some type updates and an improvement to encryption to allow selecting the secret from an option list.

This commit is contained in:
mike12345567 2023-01-16 18:15:43 +00:00
parent 5e68a4d814
commit c645a9bc21
3 changed files with 39 additions and 5 deletions

View file

@ -37,6 +37,7 @@ const environment = {
},
JS_BCRYPT: process.env.JS_BCRYPT,
JWT_SECRET: process.env.JWT_SECRET,
ENCRYPTION_KEY: process.env.ENCRYPTION_KEY,
COUCH_DB_URL: process.env.COUCH_DB_URL || "http://localhost:4005",
COUCH_DB_USERNAME: process.env.COUCH_DB_USER,
COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,

View file

@ -2,19 +2,45 @@ import crypto from "crypto"
import env from "../environment"
const ALGO = "aes-256-ctr"
const SECRET = env.JWT_SECRET
const SEPARATOR = "-"
const ITERATIONS = 10000
const RANDOM_BYTES = 16
const STRETCH_LENGTH = 32
export enum SecretOption {
JWT = "jwt",
ENCRYPTION = "encryption",
}
function getSecret(secretOption: SecretOption): string {
let secret, secretName
switch (secretOption) {
case SecretOption.ENCRYPTION:
secret = env.ENCRYPTION_KEY
secretName = "ENCRYPTION_KEY"
break
case SecretOption.JWT:
default:
secret = env.JWT_SECRET
secretName = "JWT_SECRET"
break
}
if (!secret) {
throw new Error(`Secret "${secretName}" has not been set in environment.`)
}
return secret
}
function stretchString(string: string, salt: Buffer) {
return crypto.pbkdf2Sync(string, salt, ITERATIONS, STRETCH_LENGTH, "sha512")
}
export function encrypt(input: string, secret: string | undefined = SECRET) {
export function encrypt(
input: string,
secretOption: SecretOption = SecretOption.JWT
) {
const salt = crypto.randomBytes(RANDOM_BYTES)
const stretched = stretchString(secret!, salt)
const stretched = stretchString(getSecret(secretOption), salt)
const cipher = crypto.createCipheriv(ALGO, stretched, salt)
const base = cipher.update(input)
const final = cipher.final()
@ -22,10 +48,13 @@ export function encrypt(input: string, secret: string | undefined = SECRET) {
return `${salt.toString("hex")}${SEPARATOR}${encrypted}`
}
export function decrypt(input: string, secret: string | undefined = SECRET) {
export function decrypt(
input: string,
secretOption: SecretOption = SecretOption.JWT
) {
const [salt, encrypted] = input.split(SEPARATOR)
const saltBuffer = Buffer.from(salt, "hex")
const stretched = stretchString(secret!, saltBuffer)
const stretched = stretchString(getSecret(secretOption), saltBuffer)
const decipher = crypto.createDecipheriv(ALGO, stretched, saltBuffer)
const base = decipher.update(Buffer.from(encrypted, "hex"))
const final = decipher.final()

View file

@ -14,3 +14,7 @@ export type EnvironmentVariablesDecrypted = Record<
string,
EnvironmentVariableValue
>
export interface EnvironmentVariablesDocDecrypted extends Document {
variables: EnvironmentVariablesDecrypted
}