Skip to content
Noble secretbox data encryption with AES. High-security, easily auditable, 0-dep, 1-file.
JavaScript
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.travis.yml
LICENSE
README.md
index.d.ts
index.js
index.test.js
package.json

README.md

noble-secretbox-aes-gcm

secretbox — authenticated data encryption with AES-GCM.

Allows to encrypt arbitrary data in a cryptographically secure & modern way.

This library belongs to noble crypto

noble-crypto — high-security, easily auditable set of contained cryptographic libraries and tools.

  • No dependencies, one small file
  • Easily auditable TypeScript/JS code
  • Uses es2019 bigint. Supported in Chrome, Firefox, node 10+
  • All releases are signed and trusted
  • Check out all libraries: secp256k1, ed25519, ripemd160, secretbox-aes-gcm

Usage

npm install noble-secretbox-aes-gcm

import {encrypt, decrypt, toUTF8} from "noble-secretbox-aes-gcm";
const key = Uint8Array.from([
  64, 196, 127, 247, 172,   2,  34,
  159,   6, 241,  30, 174, 183, 229,
  41, 114, 253, 122, 119, 168, 177,
  243, 155, 236, 164, 159,  98,  72,
  162, 243, 224, 195
]);
const plaintext = "Hello world";
const ciphertext = await encrypt(key, message);
const plaintext = await decrypt(key, ciphertext);
console.log(toUTF8(plaintext) === message);
// Also works in browsers

API

function encrypt(key: Uint8Array, plaintext: Uint8Array|string): Promise<Uint8Array>;

plaintext in encrypt can be either a Uint8Array, or a string. If it's a string, new TextDecoder().encode(plaintext) would be executed before passing it further.

function decrypt(key: Uint8Array, ciphertext: Uint8Array): Promise<Uint8Array>;

Note that decrypt always returns Uint8Array. If you've encrypted UTF-8 string, toUTF8(result) should be enough to get it back.

Internals

Secretbox receives one key, and one plaintext.

The output format is: iv + ciphertext + mac:

  • iv is 12 bytes; it's an initialization vector for AES-GCM mode.
  • ciphertext length depends on plaintext
  • mac is 16 bytes; AES-GCM calculates this authentication tag for us.

To slice through IV and MAC, you can use Uint8Array.prototype.slice():

const ciphertext = await encrypt(key, plaintext);
const iv = ciphertext.slice(0, 12);
const mac = ciphertext.slice(-16);

Security

Noble is production-ready & secure. Our goal is to have it audited by a good security expert.

DJB's secretbox uses XSalsa20-Poly1305. We'll use AES-GCM, which is also a good choice. DJB mentioned the AES box in his TODOs.

AES has been selected over Salsa, because it's natively implemented in Node & browsers and doesn't require any 3rd-party libraries.

NOTE: This library is a simple wrapper over aes-gcm. It does not provide key derivation a real secretbox does! You must do it by yourself.

License

MIT (c) Paul Miller (https://paulmillr.com), see LICENSE file.

You can’t perform that action at this time.