CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-peculiar--webcrypto

A WebCrypto polyfill for Node.js that provides comprehensive cryptographic operations using standard Web Crypto API

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

symmetric-encryption.mddocs/

Symmetric Encryption

Symmetric encryption algorithms using the same key for both encryption and decryption. Supports AES in multiple modes and legacy DES algorithms.

Capabilities

AES (Advanced Encryption Standard)

AES encryption support in multiple modes with key sizes of 128, 192, or 256 bits.

/**
 * AES key generation parameters
 */
interface AesKeyGenParams extends Algorithm {
  name: "AES-CBC" | "AES-CTR" | "AES-GCM" | "AES-ECB" | "AES-KW" | "AES-CMAC";
  length: 128 | 192 | 256;
}

Usage Example:

// Generate AES-256 key for GCM mode
const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 },
  true,
  ["encrypt", "decrypt"]
);

AES-CBC (Cipher Block Chaining)

Block cipher mode with initialization vector for semantic security.

/**
 * AES-CBC encryption/decryption parameters
 */
interface AesCbcParams extends Algorithm {
  name: "AES-CBC";
  iv: BufferSource; // 16 bytes initialization vector
}

Usage Example:

const key = await crypto.subtle.generateKey(
  { name: "AES-CBC", length: 256 },
  false,
  ["encrypt", "decrypt"]
);

const iv = crypto.getRandomValues(new Uint8Array(16));
const data = new TextEncoder().encode("Secret message");

const encrypted = await crypto.subtle.encrypt(
  { name: "AES-CBC", iv },
  key,
  data
);

const decrypted = await crypto.subtle.decrypt(
  { name: "AES-CBC", iv },
  key,
  encrypted
);

AES-CTR (Counter Mode)

Stream cipher mode using counter for encryption without padding.

/**
 * AES-CTR encryption/decryption parameters
 */
interface AesCtrParams extends Algorithm {
  name: "AES-CTR";
  counter: BufferSource; // 16 bytes counter block
  length: number; // Counter length in bits (1-128)
}

Usage Example:

const key = await crypto.subtle.generateKey(
  { name: "AES-CTR", length: 256 },
  false,
  ["encrypt", "decrypt"]
);

const counter = crypto.getRandomValues(new Uint8Array(16));
const data = new TextEncoder().encode("Stream cipher data");

const encrypted = await crypto.subtle.encrypt(
  { name: "AES-CTR", counter, length: 64 },
  key,
  data
);

AES-GCM (Galois/Counter Mode)

Authenticated encryption providing both confidentiality and authenticity.

/**
 * AES-GCM encryption/decryption parameters
 */
interface AesGcmParams extends Algorithm {
  name: "AES-GCM";
  iv: BufferSource; // Initialization vector (12 bytes recommended)
  additionalData?: BufferSource; // Additional authenticated data (AAD)
  tagLength?: 32 | 64 | 96 | 104 | 112 | 120 | 128; // Authentication tag length in bits
}

Usage Example:

const key = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 256 },
  false,
  ["encrypt", "decrypt"]
);

const iv = crypto.getRandomValues(new Uint8Array(12));
const additionalData = new TextEncoder().encode("authenticated-data");
const data = new TextEncoder().encode("Authenticated encrypted message");

const encrypted = await crypto.subtle.encrypt(
  { 
    name: "AES-GCM", 
    iv, 
    additionalData,
    tagLength: 128
  },
  key,
  data
);

const decrypted = await crypto.subtle.decrypt(
  { 
    name: "AES-GCM", 
    iv, 
    additionalData,
    tagLength: 128
  },
  key,
  encrypted
);

AES-ECB (Electronic Codebook)

Basic block cipher mode without initialization vector (not recommended for production).

/**
 * AES-ECB encryption/decryption parameters
 */
interface AesEcbParams extends Algorithm {
  name: "AES-ECB";
}

AES-KW (Key Wrap)

Key wrapping algorithm for securely encrypting cryptographic keys.

/**
 * AES-KW key wrapping parameters
 */
interface AesKwParams extends Algorithm {
  name: "AES-KW";
}

Usage Example:

const kek = await crypto.subtle.generateKey(
  { name: "AES-KW", length: 256 },
  false,
  ["wrapKey", "unwrapKey"]
);

const keyToWrap = await crypto.subtle.generateKey(
  { name: "AES-GCM", length: 128 },
  true,
  ["encrypt", "decrypt"]
);

const wrappedKey = await crypto.subtle.wrapKey(
  "raw",
  keyToWrap,
  kek,
  { name: "AES-KW" }
);

const unwrappedKey = await crypto.subtle.unwrapKey(
  "raw",
  wrappedKey,
  kek,
  { name: "AES-KW" },
  { name: "AES-GCM" },
  true,
  ["encrypt", "decrypt"]
);

AES-CMAC (Cipher-based Message Authentication Code)

Message authentication using AES for integrity verification.

/**
 * AES-CMAC signing/verification parameters
 */
interface AesCmacParams extends Algorithm {
  name: "AES-CMAC";
}

Usage Example:

const key = await crypto.subtle.generateKey(
  { name: "AES-CMAC", length: 256 },
  false,
  ["sign", "verify"]
);

const data = new TextEncoder().encode("Message to authenticate");

const signature = await crypto.subtle.sign(
  { name: "AES-CMAC" },
  key,
  data
);

const isValid = await crypto.subtle.verify(
  { name: "AES-CMAC" },
  key,
  signature,
  data
);

DES (Data Encryption Standard)

Legacy encryption algorithms for compatibility (use with caution).

/**
 * DES-CBC key generation parameters
 */
interface DesKeyGenParams extends Algorithm {
  name: "DES-CBC";
  length: 64; // DES key length is always 64 bits
}

/**
 * DES-CBC encryption/decryption parameters
 */
interface DesCbcParams extends Algorithm {
  name: "DES-CBC";
  iv: BufferSource; // 8 bytes initialization vector
}

/**
 * 3DES-EDE-CBC key generation parameters
 */
interface DesEde3KeyGenParams extends Algorithm {
  name: "DES-EDE3-CBC";
  length: 192; // Triple DES key length is 192 bits
}

/**
 * 3DES-EDE-CBC encryption/decryption parameters
 */
interface DesEde3CbcParams extends Algorithm {
  name: "DES-EDE3-CBC";
  iv: BufferSource; // 8 bytes initialization vector
}

Usage Example:

// Triple DES example (DES-CBC availability is platform-dependent)
const key = await crypto.subtle.generateKey(
  { name: "DES-EDE3-CBC", length: 192 },
  false,
  ["encrypt", "decrypt"]
);

const iv = crypto.getRandomValues(new Uint8Array(8));
const data = new TextEncoder().encode("Legacy encrypted data");

const encrypted = await crypto.subtle.encrypt(
  { name: "DES-EDE3-CBC", iv },
  key,
  data
);

Key Classes

AesCryptoKey

AES symmetric key implementation.

/**
 * AES symmetric cryptographic key
 */
class AesCryptoKey extends SymmetricKey {
  public algorithm: AesKeyAlgorithm;
  public type: "secret";
  public usages: KeyUsage[];
  public extractable: boolean;
}

interface AesKeyAlgorithm extends KeyAlgorithm {
  name: "AES-CBC" | "AES-CTR" | "AES-GCM" | "AES-ECB" | "AES-KW" | "AES-CMAC";
  length: 128 | 192 | 256;
}

DesCryptoKey

DES symmetric key implementation.

/**
 * DES symmetric cryptographic key
 */
class DesCryptoKey extends SymmetricKey {
  public algorithm: DesKeyAlgorithm;
  public type: "secret";
  public usages: KeyUsage[];
  public extractable: boolean;
}

interface DesKeyAlgorithm extends KeyAlgorithm {
  name: "DES-CBC" | "DES-EDE3-CBC";
  length: 64 | 192;
}

Error Handling

Common errors when working with symmetric encryption:

  • OperationError: Invalid key length, incorrect IV size, or authentication failure
  • InvalidAccessError: Key usage doesn't permit the requested operation
  • NotSupportedError: Algorithm not supported on current platform (e.g., DES-CBC)
  • DataError: Invalid parameter values or malformed encrypted data
try {
  const encrypted = await crypto.subtle.encrypt(algorithm, key, data);
} catch (error) {
  if (error.name === "OperationError") {
    // Handle encryption/decryption failures
  } else if (error.name === "InvalidAccessError") {
    // Handle key usage violations
  }
}

Install with Tessl CLI

npx tessl i tessl/npm-peculiar--webcrypto

docs

asymmetric-cryptography.md

crypto-interface.md

hash-functions.md

index.md

key-derivation.md

modern-cryptography.md

symmetric-encryption.md

tile.json