Last active
August 17, 2024 14:35
-
-
Save rjz/15baffeab434b8125ca4d783f4116d81 to your computer and use it in GitHub Desktop.
example using node.js crypto API with aes-256-gcm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const buffer = require('buffer'); | |
const crypto = require('crypto'); | |
// Demo implementation of using `aes-256-gcm` with node.js's `crypto` lib. | |
const aes256gcm = (key) => { | |
const ALGO = 'aes-256-gcm'; | |
// encrypt returns base64-encoded ciphertext | |
const encrypt = (str) => { | |
// The `iv` for a given key must be globally unique to prevent | |
// against forgery attacks. `randomBytes` is convenient for | |
// demonstration but a poor way to achieve this in practice. | |
// | |
// See: e.g. https://csrc.nist.gov/publications/detail/sp/800-38d/final | |
const iv = new Buffer(crypto.randomBytes(12), 'utf8'); | |
const cipher = crypto.createCipheriv(ALGO, key, iv); | |
// Hint: Larger inputs (it's GCM, after all!) should use the stream API | |
let enc = cipher.update(str, 'utf8', 'base64'); | |
enc += cipher.final('base64'); | |
return [enc, iv, cipher.getAuthTag()]; | |
}; | |
// decrypt decodes base64-encoded ciphertext into a utf8-encoded string | |
const decrypt = (enc, iv, authTag) => { | |
const decipher = crypto.createDecipheriv(ALGO, key, iv); | |
decipher.setAuthTag(authTag); | |
let str = decipher.update(enc, 'base64', 'utf8'); | |
str += decipher.final('utf8'); | |
return str; | |
}; | |
return { | |
encrypt, | |
decrypt, | |
}; | |
}; | |
const KEY = new Buffer(crypto.randomBytes(32), 'utf8'); | |
const aesCipher = aes256gcm(KEY); | |
const [encrypted, iv, authTag] = aesCipher.encrypt('hello, world'); | |
const decrypted = aesCipher.decrypt(encrypted, iv, authTag); | |
console.log(decrypted); // 'hello, world' |
Most applications should consider using the new KeyObject API instead of passing keys as strings or
Buffers due to improved security features. -https://nodejs.org/api/crypto.html#class-keyobject
e.g. generateKey('aes', { length: 256 }
Most applications should consider using the new KeyObject API instead of passing keys as strings or Buffers due to improved security features. -https://nodejs.org/api/crypto.html#class-keyobject
e.g.
generateKey('aes', { length: 256 }
crypto.generateKey('aes', { length: 256 }) - What exactly do you want to replace with this?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I did not implemented it, and stick to the CBC variant for now. Also, I'm not an expert and don't dear to advice anything.