Some type updates and an improvement to encryption to allow selecting the secret from an option list.
This commit is contained in:
parent
5e68a4d814
commit
c645a9bc21
|
@ -37,6 +37,7 @@ const environment = {
|
||||||
},
|
},
|
||||||
JS_BCRYPT: process.env.JS_BCRYPT,
|
JS_BCRYPT: process.env.JS_BCRYPT,
|
||||||
JWT_SECRET: process.env.JWT_SECRET,
|
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_URL: process.env.COUCH_DB_URL || "http://localhost:4005",
|
||||||
COUCH_DB_USERNAME: process.env.COUCH_DB_USER,
|
COUCH_DB_USERNAME: process.env.COUCH_DB_USER,
|
||||||
COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,
|
COUCH_DB_PASSWORD: process.env.COUCH_DB_PASSWORD,
|
||||||
|
|
|
@ -2,19 +2,45 @@ import crypto from "crypto"
|
||||||
import env from "../environment"
|
import env from "../environment"
|
||||||
|
|
||||||
const ALGO = "aes-256-ctr"
|
const ALGO = "aes-256-ctr"
|
||||||
const SECRET = env.JWT_SECRET
|
|
||||||
const SEPARATOR = "-"
|
const SEPARATOR = "-"
|
||||||
const ITERATIONS = 10000
|
const ITERATIONS = 10000
|
||||||
const RANDOM_BYTES = 16
|
const RANDOM_BYTES = 16
|
||||||
const STRETCH_LENGTH = 32
|
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) {
|
function stretchString(string: string, salt: Buffer) {
|
||||||
return crypto.pbkdf2Sync(string, salt, ITERATIONS, STRETCH_LENGTH, "sha512")
|
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 salt = crypto.randomBytes(RANDOM_BYTES)
|
||||||
const stretched = stretchString(secret!, salt)
|
const stretched = stretchString(getSecret(secretOption), salt)
|
||||||
const cipher = crypto.createCipheriv(ALGO, stretched, salt)
|
const cipher = crypto.createCipheriv(ALGO, stretched, salt)
|
||||||
const base = cipher.update(input)
|
const base = cipher.update(input)
|
||||||
const final = cipher.final()
|
const final = cipher.final()
|
||||||
|
@ -22,10 +48,13 @@ export function encrypt(input: string, secret: string | undefined = SECRET) {
|
||||||
return `${salt.toString("hex")}${SEPARATOR}${encrypted}`
|
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 [salt, encrypted] = input.split(SEPARATOR)
|
||||||
const saltBuffer = Buffer.from(salt, "hex")
|
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 decipher = crypto.createDecipheriv(ALGO, stretched, saltBuffer)
|
||||||
const base = decipher.update(Buffer.from(encrypted, "hex"))
|
const base = decipher.update(Buffer.from(encrypted, "hex"))
|
||||||
const final = decipher.final()
|
const final = decipher.final()
|
||||||
|
|
|
@ -14,3 +14,7 @@ export type EnvironmentVariablesDecrypted = Record<
|
||||||
string,
|
string,
|
||||||
EnvironmentVariableValue
|
EnvironmentVariableValue
|
||||||
>
|
>
|
||||||
|
|
||||||
|
export interface EnvironmentVariablesDocDecrypted extends Document {
|
||||||
|
variables: EnvironmentVariablesDecrypted
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue