Skip to content

Instantly share code, notes, and snippets.

@zakjan
Last active June 26, 2021 08:29
Show Gist options
  • Save zakjan/22d95d2d0b4b7a30fd62 to your computer and use it in GitHub Desktop.
Save zakjan/22d95d2d0b4b7a30fd62 to your computer and use it in GitHub Desktop.
Encryption in NodeJS
###*
* Encryption:
*
* cipher: AES-128-CBC
* key: 16 bytes
* IV: 16 bytes, random, non-reused, prepended to cipher text
* padding: PKCS#7
###
crypto = require 'crypto'
cipherName = 'aes-128-cbc'
cipherIvSize = 16
tokenSize = 16
###*
* Encrypt data
*
* @param {Buffer} key - crypto key
* @param {Buffer} data - data to encrypt
* @return {Buffer} encrypted data
###
encrypt = (key, data) ->
iv = crypto.pseudoRandomBytes(cipherIvSize)
cipher = crypto.createCipheriv(cipherName, key, iv)
cipher.setAutoPadding(true)
buf1 = cipher.update(data)
buf2 = cipher.final()
Buffer.concat([iv, buf1, buf2])
###*
* Decrypt data
*
* @param {Buffer} key - crypto key
* @param {Buffer} data - data to decrypt
* @return {Buffer} decrypted data
###
decrypt = (key, data) ->
iv = data.slice(0, cipherIvSize)
data = data.slice(cipherIvSize)
cipher = crypto.createDecipheriv(cipherName, key, iv)
cipher.setAutoPadding(true)
buf1 = cipher.update(data)
buf2 = cipher.final()
Buffer.concat([buf1, buf2])
###*
* Encrypt string
*
* @param {String} key - crypto key string (hex)
* @param {String} str - string to encrypt
* @return {String} encrypted string (base64)
###
encryptString = (key, str) ->
key = new Buffer(key, 'hex')
data = new Buffer(str)
encData = encrypt(key, data)
encData.toString('base64')
###*
* Decrypt string
*
* @param {String} key - crypto key string (hex)
* @param {String} str - string to decrypt (base64)
* @return {String} decrypted string
###
decryptString = (key, str) ->
key = new Buffer(key, 'hex')
data = new Buffer(str, 'base64')
decData = decrypt(key, data)
decData.toString()
###*
* Generate random token
*
* @return {§tring} token
###
generateRandomToken = (size = tokenSize) ->
crypto.pseudoRandomBytes(size).toString('hex')
exports.encrypt = encrypt
exports.decrypt = decrypt
exports.encryptString = encryptString
exports.decryptString = decryptString
exports.generateRandomToken = generateRandomToken
chai = require 'chai'
chai.should()
cryptoHelpers = require './cryptoHelpers'
describe 'cryptoHelpers', ->
describe 'encryptString & decryptString', ->
it 'should succeed', ->
key = 'e79455fb63d9a3c7c3e68835ac920c86' # crypto key, 16 bytes
data = '| full block || partial |' # 2 AES blocks (block size = 16 bytes), padding needed
encData = cryptoHelpers.encryptString(key, data)
decData = cryptoHelpers.decryptString(key, encData)
decData.should.equal(data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment