libsodium-wrappers

0.8.3 · active · verified Sun Apr 19

libsodium-wrappers provides a JavaScript/TypeScript binding for the highly regarded Sodium cryptographic library, compiled to WebAssembly with a pure JavaScript fallback. It is currently stable at version 0.8.3, wrapping libsodium 1.0.22. The package offers comprehensive, high-performance cryptographic operations for both web browsers (Chrome, Firefox, Edge, Safari, Mobile Safari) and server-side environments like Node.js and Bun. It comes in two variants: a standard version with commonly used functions and a 'sumo' version that includes the full, exhaustive libsodium API. Since version 0.8.1, the library automatically includes TypeScript definitions, simplifying development in typed environments. Users must `await sodium.ready` to ensure the underlying cryptographic engine is fully initialized before using any functions or constants. The library maintains a regular release cadence to incorporate upstream libsodium updates and address issues.

Common errors

Warnings

Install

Imports

Quickstart

This example demonstrates end-to-end secret stream encryption and decryption using libsodium-wrappers, showcasing key generation, message pushing with tags, and message pulling.

import sodium from 'libsodium-wrappers';

async function encryptDecryptStream() {
  await sodium.ready;

  // Generate a key for secret stream encryption
  const key = sodium.crypto_secretstream_xchacha20poly1305_keygen();

  // Initialize a push state and get the header
  const { state: state_out, header } =
    sodium.crypto_secretstream_xchacha20poly1305_init_push(key);

  // Push messages with different tags
  const message1 = sodium.from_string('This is the first secret message.');
  const c1 = sodium.crypto_secretstream_xchacha20poly1305_push(
    state_out, message1, null,
    sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE
  );

  const message2 = sodium.from_string('And this is the final message.');
  const c2 = sodium.crypto_secretstream_xchacha20poly1305_push(
    state_out, message2, null,
    sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL
  );

  console.log('Encrypted message 1 (hex):', sodium.to_hex(c1));
  console.log('Encrypted message 2 (hex):', sodium.to_hex(c2));

  // Initialize a pull state with the header and key
  const state_in = sodium.crypto_secretstream_xchacha20poly1305_init_pull(header, key);

  // Pull and decrypt the first message
  const r1 = sodium.crypto_secretstream_xchacha20poly1305_pull(state_in, c1);
  const { message: m1_bytes, tag: tag1 } = r1;
  const m1 = sodium.to_string(m1_bytes);
  console.log('Decrypted message 1:', m1, '(Tag:', tag1, ')');

  // Pull and decrypt the second (final) message
  const r2 = sodium.crypto_secretstream_xchacha20poly1305_pull(state_in, c2);
  const { message: m2_bytes, tag: tag2 } = r2;
  const m2 = sodium.to_string(m2_bytes);
  console.log('Decrypted message 2:', m2, '(Tag:', tag2, ')');

  // Ensure the tags are correct
  if (tag1 === sodium.crypto_secretstream_xchacha20poly1305_TAG_MESSAGE &&
      tag2 === sodium.crypto_secretstream_xchacha20poly1305_TAG_FINAL) {
    console.log('Stream messages successfully encrypted and decrypted with correct tags.');
  } else {
    console.error('Tag mismatch!');
  }
}

encryptDecryptStream();

view raw JSON →