CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-sodium-native

Low level bindings for libsodium cryptographic library

Pending
Overview
Eval results
Files

secretbox.mddocs/

Secret Key Encryption

Symmetric authenticated encryption using the crypto_secretbox construction (XSalsa20 + Poly1305) for protecting data with shared keys.

Capabilities

Easy Mode Encryption

Encrypts a message using a secret key and nonce, producing authenticated ciphertext.

/**
 * Encrypt message using secret key (authenticated encryption)
 * @param c - Output buffer for ciphertext (must be m.length + MACBYTES)
 * @param m - Message buffer to encrypt
 * @param n - Nonce buffer (must be NONCEBYTES long)
 * @param k - Secret key buffer (must be KEYBYTES long)
 * @throws Error if buffer sizes are incorrect or encryption fails
 */
function crypto_secretbox_easy(c: Buffer, m: Buffer, n: Buffer, k: Buffer): void;

Easy Mode Decryption

Decrypts and verifies authenticated ciphertext using a secret key and nonce.

/**
 * Decrypt and verify ciphertext using secret key
 * @param m - Output buffer for plaintext (must be c.length - MACBYTES)
 * @param c - Ciphertext buffer to decrypt
 * @param n - Nonce buffer (must be NONCEBYTES long)
 * @param k - Secret key buffer (must be KEYBYTES long)
 * @returns true if decryption successful, false if verification fails
 * @throws Error if buffer sizes are incorrect
 */
function crypto_secretbox_open_easy(m: Buffer, c: Buffer, n: Buffer, k: Buffer): boolean;

Usage Example:

const sodium = require('sodium-native');

// Generate key and nonce
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES);
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES);
sodium.randombytes_buf(key);
sodium.randombytes_buf(nonce);

// Encrypt a message
const message = Buffer.from('Hello, World!');
const ciphertext = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES);
sodium.crypto_secretbox_easy(ciphertext, message, nonce, key);

// Decrypt the message
const plaintext = Buffer.alloc(ciphertext.length - sodium.crypto_secretbox_MACBYTES);
if (sodium.crypto_secretbox_open_easy(plaintext, ciphertext, nonce, key)) {
  console.log('Decrypted:', plaintext.toString());
} else {
  console.log('Decryption failed - invalid ciphertext or key');
}

Detached Mode Encryption

Encrypts a message with the authentication tag stored separately from the ciphertext.

/**
 * Encrypt message with detached authentication tag
 * @param c - Output buffer for ciphertext (must be same length as message)
 * @param mac - Output buffer for authentication tag (must be MACBYTES long)
 * @param m - Message buffer to encrypt
 * @param n - Nonce buffer (must be NONCEBYTES long)
 * @param k - Secret key buffer (must be KEYBYTES long)
 * @throws Error if buffer sizes are incorrect or encryption fails
 */
function crypto_secretbox_detached(c: Buffer, mac: Buffer, m: Buffer, n: Buffer, k: Buffer): void;

Detached Mode Decryption

Decrypts a message using a separate authentication tag.

/**
 * Decrypt message with detached authentication tag
 * @param m - Output buffer for plaintext (must be same length as ciphertext)
 * @param c - Ciphertext buffer to decrypt
 * @param mac - Authentication tag buffer (must be MACBYTES long)
 * @param n - Nonce buffer (must be NONCEBYTES long)
 * @param k - Secret key buffer (must be KEYBYTES long)
 * @returns true if decryption successful, false if verification fails
 * @throws Error if buffer sizes are incorrect
 */
function crypto_secretbox_open_detached(m: Buffer, c: Buffer, mac: Buffer, n: Buffer, k: Buffer): boolean;

Usage Example:

const sodium = require('sodium-native');

// Generate key and nonce
const key = Buffer.alloc(sodium.crypto_secretbox_KEYBYTES);
const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES);
sodium.randombytes_buf(key);
sodium.randombytes_buf(nonce);

// Encrypt with detached MAC
const message = Buffer.from('Secret message');
const ciphertext = Buffer.alloc(message.length);
const mac = Buffer.alloc(sodium.crypto_secretbox_MACBYTES);

sodium.crypto_secretbox_detached(ciphertext, mac, message, nonce, key);

// Decrypt with detached MAC
const plaintext = Buffer.alloc(ciphertext.length);
if (sodium.crypto_secretbox_open_detached(plaintext, ciphertext, mac, nonce, key)) {
  console.log('Decrypted:', plaintext.toString());
} else {
  console.log('Authentication failed');
}

Constants

// Secret key size in bytes
const crypto_secretbox_KEYBYTES: number;

// Nonce size in bytes
const crypto_secretbox_NONCEBYTES: number;

// Authentication tag size in bytes
const crypto_secretbox_MACBYTES: number;

Security Considerations

  • Nonce Reuse: Never reuse a nonce with the same key. Each encryption operation must use a unique nonce.
  • Key Management: Keep secret keys secure and use sodium_malloc() for secure key storage.
  • Authentication: The Poly1305 authenticator ensures ciphertext integrity and authenticity.
  • Timing Safety: All operations are designed to be timing-attack resistant.

Common Patterns

File Encryption

const sodium = require('sodium-native');
const fs = require('fs');

function encryptFile(inputFile, outputFile, key) {
  const plaintext = fs.readFileSync(inputFile);
  const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES);
  sodium.randombytes_buf(nonce);
  
  const ciphertext = Buffer.alloc(plaintext.length + sodium.crypto_secretbox_MACBYTES);
  sodium.crypto_secretbox_easy(ciphertext, plaintext, nonce, key);
  
  // Prepend nonce to ciphertext for storage
  const encrypted = Buffer.concat([nonce, ciphertext]);
  fs.writeFileSync(outputFile, encrypted);
}

function decryptFile(inputFile, outputFile, key) {
  const encrypted = fs.readFileSync(inputFile);
  const nonce = encrypted.subarray(0, sodium.crypto_secretbox_NONCEBYTES);
  const ciphertext = encrypted.subarray(sodium.crypto_secretbox_NONCEBYTES);
  
  const plaintext = Buffer.alloc(ciphertext.length - sodium.crypto_secretbox_MACBYTES);
  if (sodium.crypto_secretbox_open_easy(plaintext, ciphertext, nonce, key)) {
    fs.writeFileSync(outputFile, plaintext);
    return true;
  }
  return false;
}

Message Encryption with Counter

const sodium = require('sodium-native');

class SecretBoxWithCounter {
  constructor(key) {
    this.key = key;
    this.counter = 0n;
  }
  
  encrypt(message) {
    const nonce = Buffer.alloc(sodium.crypto_secretbox_NONCEBYTES);
    nonce.writeBigUInt64LE(this.counter++, 0);
    
    const ciphertext = Buffer.alloc(message.length + sodium.crypto_secretbox_MACBYTES);
    sodium.crypto_secretbox_easy(ciphertext, message, nonce, this.key);
    
    return { ciphertext, nonce };
  }
  
  decrypt(ciphertext, nonce) {
    const plaintext = Buffer.alloc(ciphertext.length - sodium.crypto_secretbox_MACBYTES);
    if (sodium.crypto_secretbox_open_easy(plaintext, ciphertext, nonce, this.key)) {
      return plaintext;
    }
    return null;
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-sodium-native

docs

aead.md

auth.md

box.md

ed25519.md

hash.md

index.md

kdf.md

kx.md

memory.md

pwhash.md

random.md

secretbox.md

secretstream.md

shorthash.md

sign.md

stream.md

tile.json