Skip to main content
The symmetric encryption module provides functions for encrypting and decrypting data using secret-key authenticated encryption (NaCl secretbox). All functions support typed data through the Datagram pattern.

generateSymmetricKey

Generates a random symmetric key for encryption.
function generateSymmetricKey(): string

Returns

symmetricKey
string
required
Base64-encoded symmetric key suitable for use with encryptSymmetric and decryptSymmetric

Example

import { generateSymmetricKey } from 'skiff-crypto';

const symmetricKey = generateSymmetricKey();
console.log(symmetricKey); // "base64-encoded-key..."

encryptSymmetric

Encrypts data using symmetric encryption with NaCl secretbox (secret-key authenticated encryption).
function encryptSymmetric<T>(
  content: T,
  symmetricKey: string,
  datagram: Datagram<T>
): string

Parameters

content
T
required
The object to encrypt. Type must match the Datagram type parameter.
symmetricKey
string
required
Base64-encoded symmetric key generated by generateSymmetricKey()
datagram
Datagram<T>
required
The datagram that defines how to serialize and deserialize the data. Common datagrams:
  • createRawJSONDatagram<T>(type, version?, versionConstraint?) - For JSON-serializable data
  • createRawCompressedJSONDatagram<T>(type, version?, versionConstraint?) - For compressed JSON data
  • createUint8ArrayDatagram(type, version?, versionConstraint?) - For raw binary data

Returns

encrypted
string
required
Base64-encoded encrypted payload including metadata and ciphertext

Example

import { encryptSymmetric, generateSymmetricKey } from 'skiff-crypto';
import { createRawJSONDatagram } from 'skiff-crypto';

interface UserData {
  email: string;
  preferences: Record<string, any>;
}

// Create a datagram for the data type
const UserDataDatagram = createRawJSONDatagram<UserData>('UserData');

// Generate key and encrypt
const key = generateSymmetricKey();
const userData: UserData = {
  email: '[email protected]',
  preferences: { theme: 'dark' }
};

const encrypted = encryptSymmetric(userData, key, UserDataDatagram);
console.log(encrypted); // "base64-encoded-encrypted-data..."

decryptSymmetric

Decrypts data that was encrypted with encryptSymmetric using NaCl secretbox.
function decryptSymmetric<T>(
  message: string,
  symmetricKey: string,
  DatagramType: Datagram<T>
): T

Parameters

message
string
required
Base64-encoded encrypted payload returned from encryptSymmetric()
symmetricKey
string
required
Base64-encoded symmetric key used for encryption
DatagramType
Datagram<T>
required
The same datagram used during encryption. Version constraints are validated during decryption.

Returns

decrypted
T
required
The decrypted data object, deserialized according to the datagram

Errors

Throws an error if:
  • The message cannot be decrypted (wrong key, corrupted data)
  • The datagram version constraint doesn’t match the encrypted data version
  • The datagram type doesn’t match the encrypted data type

Example

import { decryptSymmetric } from 'skiff-crypto';
import { createRawJSONDatagram } from 'skiff-crypto';

interface UserData {
  email: string;
  preferences: Record<string, any>;
}

const UserDataDatagram = createRawJSONDatagram<UserData>('UserData');

try {
  const decrypted = decryptSymmetric(
    encryptedMessage,
    symmetricKey,
    UserDataDatagram
  );
  console.log(decrypted.email); // "[email protected]"
} catch (error) {
  console.error('Decryption failed:', error.message);
}

rawEncryptSymmetric

Encrypts data and returns raw bytes without base64 encoding.
function rawEncryptSymmetric<T>(
  content: T,
  symmetricKey: string,
  datagram: Datagram<T>
): Uint8Array

Parameters

content
T
required
The object to encrypt
symmetricKey
string
required
Base64-encoded symmetric key
datagram
Datagram<T>
required
The datagram for serialization

Returns

encrypted
Uint8Array
required
Raw encrypted payload as a byte array

rawDecryptSymmetric

Decrypts raw encrypted bytes.
function rawDecryptSymmetric<T>(
  message: Uint8Array,
  symmetricKey: string,
  DatagramType: Datagram<T>
): T

Parameters

message
Uint8Array
required
Raw encrypted payload from rawEncryptSymmetric()
symmetricKey
string
required
Base64-encoded symmetric key
DatagramType
Datagram<T>
required
The datagram for deserialization

Returns

decrypted
T
required
The decrypted data object

Datagram Types

Datagrams define how data is serialized before encryption and deserialized after decryption. They also include versioning information.

createRawJSONDatagram

Creates a datagram for JSON-serializable data.
function createRawJSONDatagram<T>(
  type: string,
  version?: string,  // default: '0.1.0'
  versionConstraint?: Range  // default: new Range('0.1.*')
): Datagram<T>

createRawCompressedJSONDatagram

Creates a datagram that compresses JSON data with gzip before encryption.
function createRawCompressedJSONDatagram<T>(
  type: string,
  version?: string,  // default: '0.1.0'
  versionConstraint?: Range  // default: new Range('0.1.*')
): Datagram<T>

createUint8ArrayDatagram

Creates a datagram for raw binary data (no serialization).
function createUint8ArrayDatagram(
  type: string,
  version?: string,  // default: '0.1.0'
  versionConstraint?: Range  // default: new Range('0.1.*')
): Datagram<Uint8Array>

Version Compatibility

Datagrams support version constraints using semver ranges. During decryption, the library validates that the encrypted data’s version satisfies the datagram’s version constraint.
import { Range } from 'semver';
import { createRawJSONDatagram } from 'skiff-crypto';

// Accept any 0.1.x version
const DatagramV1 = createRawJSONDatagram('MyData', '0.1.0', new Range('0.1.*'));

// Only accept 0.2.0
const DatagramV2 = createRawJSONDatagram('MyData', '0.2.0', new Range('0.2.0'));

// Data encrypted with DatagramV1 can be decrypted with any 0.1.x datagram
// but will throw an error if decrypted with DatagramV2

Build docs developers (and LLMs) love