encrypt

Symmetric encryption and decryption streams. Defaults to AES-256-GCM (authenticated encryption).

Install

npm install @datastream/encrypt

For ChaCha20-Poly1305 in browser environments:

npm install libsodium-wrappers

encryptStream Transform async (browser)

Encrypts data passing through. On Node.js, wraps node:crypto for true streaming. In the browser, uses Web Crypto API (AES-GCM buffers; AES-CTR streams).

Options

OptionTypeDefaultDescription
algorithmstring"AES-256-GCM"Encryption algorithm
keyUint8Array\|Buffer32-byte encryption key
ivUint8Array\|Bufferauto-generatedInitialization vector
aadUint8Array\|BufferAdditional Authenticated Data (GCM/ChaCha only)
maxInputSizenumber67108864Max input bytes for web AES-GCM (64MB)

Supported algorithms

AlgorithmAuthNode.jsBrowserIV size
AES-256-GCMauthTagnode:crypto (streaming)crypto.subtle (buffered)12 bytes
AES-256-CTRnonenode:crypto (streaming)crypto.subtle (streaming)16 bytes
CHACHA20-POLY1305authTagnode:crypto (streaming)libsodium-wrappers (buffered)12 bytes

Result

{
  algorithm: 'AES-256-GCM',
  iv: Uint8Array(12),
  authTag: Uint8Array(16)  // only for GCM and ChaCha20
}

Example

import { createReadableStream, pipeline } from '@datastream/core'
import { encryptStream, generateEncryptionKey } from '@datastream/encrypt'

const key = generateEncryptionKey()

// Node.js — synchronous
const enc = encryptStream({ key })

const result = await pipeline([
  createReadableStream(data),
  enc,
])

const { iv, authTag } = result.encrypt
// Browser — async, must await
const enc = await encryptStream({ key })

decryptStream Transform async (browser)

Decrypts data encrypted by encryptStream.

Options

OptionTypeDefaultDescription
algorithmstring"AES-256-GCM"Must match encryption algorithm
keyUint8Array\|BufferSame key used for encryption
ivUint8Array\|BufferIV from encryptStream result
authTagUint8Array\|BufferAuth tag from result (GCM/ChaCha)
aadUint8Array\|BufferMust match encryption AAD
maxOutputSizenumberMax decrypted output bytes

Example

import { createReadableStream, pipeline, streamToString } from '@datastream/core'
import { decryptStream } from '@datastream/encrypt'

const dec = decryptStream({ key, iv, authTag })

const plaintext = await streamToString(
  createReadableStream(ciphertext).pipe(dec)
)

generateEncryptionKey

Generate a cryptographically random encryption key.

import { generateEncryptionKey } from '@datastream/encrypt'

const key = generateEncryptionKey()              // 32 bytes (AES-256)
const key = generateEncryptionKey({ bits: 128 }) // 16 bytes (AES-128)

Patterns

Encrypt with plaintext and ciphertext digests

import { pipeline } from '@datastream/core'
import { fileReadStream, fileWriteStream } from '@datastream/file'
import { encryptStream } from '@datastream/encrypt'
import { digestStream } from '@datastream/digest'

const result = await pipeline([
  fileReadStream({ path: './data.csv' }),
  digestStream({ algorithm: 'SHA2-256', resultKey: 'plaintextDigest' }),
  encryptStream({ key }),
  digestStream({ algorithm: 'SHA2-256', resultKey: 'ciphertextDigest' }),
  fileWriteStream({ path: './data.csv.enc' }),
])

// result.plaintextDigest  — verify correct decryption
// result.ciphertextDigest — verify file integrity on disk
// result.encrypt          — { algorithm, iv, authTag }

Large file streaming with AES-CTR

AES-256-CTR supports true streaming on both Node.js and browser. Use it for large files where AES-GCM’s buffering would cause memory issues. Pair with digestStream for integrity verification.

import { encryptStream } from '@datastream/encrypt'

const enc = await encryptStream({ key, algorithm: 'AES-256-CTR' })

With Additional Authenticated Data (AAD)

Bind encryption to metadata so ciphertext can’t be reused in a different context.

const aad = new TextEncoder().encode(JSON.stringify({ userId: '123' }))
const enc = encryptStream({ key, aad })
// Decryption must provide the same aad
const dec = decryptStream({ key, iv, authTag, aad })