Skip to content
Noble secretbox data encryption with AES. High-security, easily auditable, 0-dep, 1-file.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


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


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


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.


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);


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.


MIT (c) Paul Miller (, see LICENSE file.

You can’t perform that action at this time.