Skip to content

Instantly share code, notes, and snippets.

@Mix-Liten
Last active August 24, 2023 10:31
Show Gist options
  • Save Mix-Liten/1ba954c8f5d11af0bc632fdcd037db04 to your computer and use it in GitHub Desktop.
Save Mix-Liten/1ba954c8f5d11af0bc632fdcd037db04 to your computer and use it in GitHub Desktop.
Symmetric Encryption in Node.js
const { createCipheriv, createDecipheriv, randomBytes } = require('crypto')
/**
* A class for symmetric encryption and decryption using AES-GCM.
*/
class SymmetricEncryptor {
#key
/**
* Create a new SymmetricEncryptor instance.
* @param {string} key - The base64-encoded encryption key.
*/
constructor(key) {
/**
* @private
*/
this.#key = Buffer.from(key, 'base64')
}
/**
* Encrypts the given plaintext using AES-GCM.
* @param {string} plaintext - The plaintext message to encrypt.
* @returns {Object} An object containing the ciphertext, initialization vector (IV), and authentication tag.
*/
encrypt(plaintext) {
const iv = randomBytes(12).toString('base64')
const cipher = createCipheriv('aes-256-gcm', this.#key, Buffer.from(iv, 'base64'))
let ciphertext = cipher.update(plaintext, 'utf8', 'base64')
ciphertext += cipher.final('base64')
const authTag = cipher.getAuthTag()
return { ciphertext, iv, authTag }
}
/**
* Decrypts the given ciphertext using AES-GCM.
* @param {string} ciphertext - The ciphertext to decrypt.
* @param {string} iv - The initialization vector (IV) used during encryption.
* @param {string} authTag - The authentication tag generated during encryption.
* @returns {string} The decrypted plaintext message.
*/
decrypt(ciphertext, iv, authTag) {
const decipher = createDecipheriv('aes-256-gcm', this.#key, Buffer.from(iv, 'base64'))
decipher.setAuthTag(Buffer.from(authTag, 'base64'))
let plaintext = decipher.update(ciphertext, 'base64', 'utf8')
plaintext += decipher.final('utf8')
return plaintext
}
}
// Example usage
const plaintext = '----- Secret Data -----'
const key = randomBytes(32).toString('base64')
const symmetricEncryptor = new SymmetricEncryptor(key)
console.log('Init sample:', { plaintext, key })
const { ciphertext, iv, authTag } = symmetricEncryptor.encrypt(plaintext)
console.log('Encrypted return:', { ciphertext, iv, authTag })
const decryptedPlaintext = symmetricEncryptor.decrypt(ciphertext, iv, authTag)
console.log('Decrypted Plaintext:', decryptedPlaintext)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment