Skip to content

Instantly share code, notes, and snippets.

@rigwild
Last active December 20, 2022 18:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rigwild/a4f4cf1527bc044dbbc92f37f727484e to your computer and use it in GitHub Desktop.
Save rigwild/a4f4cf1527bc044dbbc92f37f727484e to your computer and use it in GitHub Desktop.
`aes-256-gcm` encryption with native crypto module
const crypto = require('crypto')
/**
* Encrypts text by given key
* @param {string} text to encrypt
* @param {Buffer | string} masterkey
* @returns {string} encrypted text, base64 encoded
*/
function encrypt(text, masterkey) {
// random initialization vector
const iv = crypto.randomBytes(16)
// random salt
const salt = crypto.randomBytes(64)
// derive encryption key: 32 byte key length
// in assumption the masterkey is a cryptographic and NOT a password there is no need for
// a large number of iterations. It may can replaced by HKDF
// the value of 2145 is randomly chosen!
const key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512')
// AES 256 GCM Mode
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv)
// encrypt the given text
const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()])
// extract the auth tag
const tag = cipher.getAuthTag()
// generate output
return Buffer.concat([salt, iv, tag, encrypted]).toString('base64')
}
/**
* Decrypts text by given key
* @param {string} encdata encoded input data
* @param {Buffer | string} masterkey
* @returns {string} decrypted (original) text
*/
function decrypt(encdata, masterkey) {
// base64 decoding
const bData = Buffer.from(encdata, 'base64')
// convert data to buffers
const salt = bData.slice(0, 64)
const iv = bData.slice(64, 80)
const tag = bData.slice(80, 96)
const text = bData.slice(96)
// derive key using; 32 byte key length
const key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512')
// AES 256 GCM Mode
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv)
decipher.setAuthTag(tag)
// encrypt the given text
const decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8')
return decrypted
}
// Usage
// Get a random secret key, or your own
const secret = [...Array(50)].map(() => Math.random().toString(36)[2]).join('')
// const secret = 'this is my safe secret 123'
const key = crypto.createHash('sha256').update(String(secret)).digest('base64').substr(0, 32)
const str = 'hello world!'
const encrypted = encrypt(str, key)
console.log(encrypted)
const decrypted = decrypt(encrypted, key)
console.log(str === decrypted, decrypted)
import crypto from 'crypto'
/** Encrypt text by given key */
function encrypt(text: string, masterkey: Buffer | string): string {
// random initialization vector
const iv = crypto.randomBytes(16)
// random salt
const salt = crypto.randomBytes(64)
// derive encryption key: 32 byte key length
// in assumption the masterkey is a cryptographic and NOT a password there is no need for
// a large number of iterations. It may can replaced by HKDF
// the value of 2145 is randomly chosen!
const key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512')
// AES 256 GCM Mode
const cipher = crypto.createCipheriv('aes-256-gcm', key, iv)
// encrypt the given text
const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()])
// extract the auth tag
const tag = cipher.getAuthTag()
// generate output
return Buffer.concat([salt, iv, tag, encrypted]).toString('base64')
}
/** Decrypt text by given key */
function decrypt(encdata: string, masterkey: Buffer | string): string {
// base64 decoding
const bData = Buffer.from(encdata, 'base64')
// convert data to buffers
const salt = bData.slice(0, 64)
const iv = bData.slice(64, 80)
const tag = bData.slice(80, 96)
const text = bData.slice(96)
// derive key using; 32 byte key length
const key = crypto.pbkdf2Sync(masterkey, salt, 2145, 32, 'sha512')
// AES 256 GCM Mode
const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv)
decipher.setAuthTag(tag)
// encrypt the given text
// const decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8')
const decrypted = decipher.update(text.toString('binary'), 'binary', 'utf8') + decipher.final('utf8')
// const decrypted = decipher.update(text, 'binary', 'utf8') + decipher.final('utf8')
return decrypted
}
// Usage
// Get a random secret key, or your own
const secret = [...Array(50)].map(() => Math.random().toString(36)[2]).join('')
// const secret = 'this is my safe secret 123'
const key = crypto.createHash('sha256').update(String(secret)).digest('base64').substr(0, 32)
const str = 'hello world!'
const encrypted = encrypt(str, key)
console.log(encrypted)
const decrypted = decrypt(encrypted, key)
console.log(str === decrypted, decrypted)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment