feature: the credential store keeps credentials of any kind in config.json with encrypted secrets, with its routes and its dialog.
Release / release (push) Successful in 1m4s
Release / release (push) Successful in 1m4s
This commit is contained in:
1 parent
57ac5296cb
commit
b0b7a4bb7f
13 files changed
+723
-30
No files matched your search
@@ -0,0 +1,38 @@
|
||||
import { createCipheriv, createDecipheriv, createHash, randomBytes } from 'node:crypto'
|
||||
import { readFileSync } from 'node:fs'
|
||||
|
||||
const ALGORITHM = 'aes-256-gcm'
|
||||
const IV_BYTES = 12
|
||||
const TAG_BYTES = 16
|
||||
|
||||
/**
|
||||
* The key of the secrets: the SHA-256 of ENCRYPTION_KEY, else of the content of the file ENCRYPTION_KEY_FILE names
|
||||
* without its final newline; null when neither is set. A file that cannot be read throws with the reason.
|
||||
*/
|
||||
export function encryptionKey(): Buffer | null {
|
||||
let secret = process.env.ENCRYPTION_KEY
|
||||
if (!secret && process.env.ENCRYPTION_KEY_FILE) {
|
||||
try {
|
||||
secret = readFileSync(process.env.ENCRYPTION_KEY_FILE, 'utf8').replace(/\r?\n$/, '')
|
||||
} catch (error) {
|
||||
throw new Error(`ENCRYPTION_KEY_FILE ${process.env.ENCRYPTION_KEY_FILE} cannot be read: ${(error as Error).message}`)
|
||||
}
|
||||
}
|
||||
return secret ? createHash('sha256').update(secret, 'utf8').digest() : null
|
||||
}
|
||||
|
||||
/** The text encrypted with AES-256-GCM: base64 of a random IV, the ciphertext and the authentication tag. */
|
||||
export function encrypt(text: string, key: Buffer): string {
|
||||
const iv = randomBytes(IV_BYTES)
|
||||
const cipher = createCipheriv(ALGORITHM, key, iv)
|
||||
const data = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()])
|
||||
return Buffer.concat([iv, data, cipher.getAuthTag()]).toString('base64')
|
||||
}
|
||||
|
||||
/** The text of encrypt's answer; another key, or a changed answer, throws. */
|
||||
export function decrypt(encrypted: string, key: Buffer): string {
|
||||
const bytes = Buffer.from(encrypted, 'base64')
|
||||
const decipher = createDecipheriv(ALGORITHM, key, bytes.subarray(0, IV_BYTES))
|
||||
decipher.setAuthTag(bytes.subarray(bytes.length - TAG_BYTES))
|
||||
return Buffer.concat([decipher.update(bytes.subarray(IV_BYTES, bytes.length - TAG_BYTES)), decipher.final()]).toString('utf8')
|
||||
}
|
||||
Reference in new issue
Block a user