| | import crypto from 'crypto' |
| |
|
| | |
| | |
| |
|
| | const CIPHER_ALGORITHM = `aes-256-gcm`, |
| | CIPHER_KEY_LENGTH = 32, |
| | CIPHER_IV_LENGTH = 16, |
| | CIPHER_TAG_LENGTH = 16, |
| | CIPHER_SALT_LENGTH = 64 |
| |
|
| | const PBKDF2_ITERATIONS = 100_000 |
| |
|
| | export function encryptWithSecret(secret: Buffer, data: string): string { |
| | const iv = crypto.randomBytes(CIPHER_IV_LENGTH) |
| | const salt = crypto.randomBytes(CIPHER_SALT_LENGTH) |
| |
|
| | |
| | const key = crypto.pbkdf2Sync( |
| | secret, |
| | salt, |
| | PBKDF2_ITERATIONS, |
| | CIPHER_KEY_LENGTH, |
| | `sha512` |
| | ) |
| |
|
| | const cipher = crypto.createCipheriv(CIPHER_ALGORITHM, key, iv) |
| | const encrypted = Buffer.concat([cipher.update(data, `utf8`), cipher.final()]) |
| |
|
| | |
| | const tag = cipher.getAuthTag() |
| |
|
| | return Buffer.concat([ |
| | |
| | |
| | |
| | |
| | salt, |
| | iv, |
| | tag, |
| | encrypted, |
| | ]).toString(`hex`) |
| | } |
| |
|
| | export function decryptWithSecret( |
| | secret: Buffer, |
| | encryptedData: string |
| | ): string { |
| | const buffer = Buffer.from(encryptedData, `hex`) |
| |
|
| | const salt = buffer.slice(0, CIPHER_SALT_LENGTH) |
| | const iv = buffer.slice( |
| | CIPHER_SALT_LENGTH, |
| | CIPHER_SALT_LENGTH + CIPHER_IV_LENGTH |
| | ) |
| | const tag = buffer.slice( |
| | CIPHER_SALT_LENGTH + CIPHER_IV_LENGTH, |
| | CIPHER_SALT_LENGTH + CIPHER_IV_LENGTH + CIPHER_TAG_LENGTH |
| | ) |
| | const encrypted = buffer.slice( |
| | CIPHER_SALT_LENGTH + CIPHER_IV_LENGTH + CIPHER_TAG_LENGTH |
| | ) |
| |
|
| | |
| | const key = crypto.pbkdf2Sync( |
| | secret, |
| | salt, |
| | PBKDF2_ITERATIONS, |
| | CIPHER_KEY_LENGTH, |
| | `sha512` |
| | ) |
| |
|
| | const decipher = crypto.createDecipheriv(CIPHER_ALGORITHM, key, iv) |
| | decipher.setAuthTag(tag) |
| |
|
| | return decipher.update(encrypted) + decipher.final(`utf8`) |
| | } |
| |
|