Skip to content

Instantly share code, notes, and snippets.

@cgutwin
Last active May 24, 2024 06:07
Show Gist options
  • Save cgutwin/4aba40fbada47ff7d6af9c2c4b26b2e2 to your computer and use it in GitHub Desktop.
Save cgutwin/4aba40fbada47ff7d6af9c2c4b26b2e2 to your computer and use it in GitHub Desktop.
Two-way encryption for user data (in this case, an account password) utilizing three different values for the encryption key, with NodeJS.
/*
* Encryption for the added user accounts and passwords
*
* Reference:
* https://stackoverflow.com/a/5093422
* */
require('dotenv').config()
const CRYPTO = require('crypto')
const Encryption = require('./Encryption')
class AccountEncryption extends Encryption {
constructor(props) {
super(props)
}
//Encrypts the user data, based on the supplied data, and the user information.
async encrypt(data, user) {
const iv = super.generateRandomBytes(8)
const key = await this.createKey(user.ukey, iv, user.password)
const cipher = await CRYPTO.createCipheriv('aes-256-cbc', key, iv);
const encrypted = cipher.update(data, 'ascii', 'hex') + cipher.final('hex')
return `${iv}.${encrypted}`
}
//Will decrypt the data by regenerating the key.
async decrypt(data, user) {
const split = data.split('.')
const salt = split[0]
const enc = split[1]
const key = await this.createKey(user.ukey, salt, user.password)
const decipher = await CRYPTO.createDecipheriv('aes-256-cbc', key, salt)
return decipher.update(enc, 'hex', 'ascii') + decipher.final('ascii')
}
//The key, based off of three separate values. One for the server, one unique user id, and the user's password.
async createKey(user, salt, supplied) {
//split the combined iterations.salt.hash for just the hash.
let suppliedHash = supplied.split('.')[2]
let key = `${user}.${process.env.SERVER_KEY}.${suppliedHash}`
return await CRYPTO.pbkdf2Sync(key, salt, 20000, 16, 'sha512').toString('hex')
}
}
module.exports = AccountEncryption
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment