aes-gcm-stream

A dependency free NodeJS module that implements AES256 GCM encryption and decryption as transform streams.

Usage no npm install needed!

<script type="module">
  import aesGcmStream from 'https://cdn.skypack.dev/aes-gcm-stream';
</script>

README

aes-gcm-stream

A NodeJS Module with no dependencies that implements AES256 GCM encryption and decryption using streams. This module requires node v.0.12.0+ as it relies on its updated crypto library.

Installation

This module can be brought into your project using NPM:

npm install aes-gcm-stream --save

Why does this module exist?

It's non-trivial to use GCM mode in NodeJS for more than simple string and buffer data. By implementing GCM encryption and decryption as transform streams it's easier to do complex tasks like encrypting data coming from child processes (like database dumps) or files while still using authenticated encryption.

What is authenticated encryption and why should I care?

Authenticated encryption is a way of ensuring both confidentially AND integrity of data. Using GCM we can be certain that the cipher text has not been tampered with and that only someone in possession of the secret key could have been the author.

What are the downsides to this module?

The main downside is that the entirety of the data you're trying to decrypt at any one time needs to fit in memory. So if your data is very large and/or you're memory constrained this module will probably not be a good fit. To authenticate and decrypt data secured with GCM both the nonce used during encryption and the MAC generated by the encryption cipher are needed BEFORE decryption can begin. This is what makes using GCM mode with streams in Node so painful in the first place.

This module handles that by having the decrypter store all of the cipher text in memory until the stream is flushed. Because the encrypter sends the MAC as the final chunk of the stream the decrypter can safely assume the first 12 bytes it receives are a nonce and the final 16 bytes of the cipher text are the MAC. When the decryption stream is flushed it calls setAuthTag, and updates the decipher with the entire cipher text buffer, this results in either the decrypted data being output or an error being thrown if decryption fails.

Usage Examples

Robustly documented usage examples are provided in the examples directory of the repository.

Each of these examples can be run using node, and are intended to be run from the examples directory:

cd examples
node with-strings.js

Keys

Helper methods are provided to generate encoded keys which can be written to disk or STDOUT. A key MUST be passed via the options hash to the encrypter and decrypter. Keys should be kept safe and shared securely. See the examples directory for code to read encoded keys from disk and use them.

Nonces

The encrypter can be explicitly passed a nonce in the constructor's options object, if one is not passed in, one will be securely generated automatically. It's recommended that you allow the encrypter to generate its own nonce as it hopefully discourages reuse of the same nonce for additional encryption streams.

Calling End

Remember that if you're not using pipe to get data into the encrypter but are explicitly calling write on the stream, it's necessary to also explicitly call end on the stream before the MAC of the cipher text will be output. The with-strings.js example file shows this in detail.

If you're using pipe then flushing will happen automatically. See the with-a-file.js example for more.

Contributing

Issues and pull requests are welcome! If you're interested in opening a PR please ensure jscs and jshint compliance.