npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

ts-aes-cbc

v1.0.0

Published

TypeScript port of WjCryptLib's AES-CBC (NIST SP 800-38A §F.2). AES-128/192/256.

Readme

ts-aes-cbc

A direct TypeScript port of WjCryptLib's AES-CBC implementation. AES-128/192/256 in CBC mode of operation.

If you find this project useful, you can support this and further ports at ko-fi.com/scottmoore0.

Upstream provenance

Direct port of WaterJuice/WjCryptLib (WjCryptLib_Aes.c core + WjCryptLib_AesCbc.c mode wrapper), Unlicense / public domain.

The translated output is validated against NIST SP 800-38A §F.2.1, §F.2.3, §F.2.5 test vectors covering all three AES key sizes.

Why this exists

AES-CBC is the most widely deployed authenticated-encryption-prerequisite mode of operation: TLS 1.0/1.1, IPsec ESP, SSH, OpenPGP, LUKS, plus countless application protocols. CBC chains each block's encryption against the previous ciphertext block via XOR, providing diffusion across the entire message at the cost of being inherently sequential.

This package exposes a clean Uint8Array API on top of the WjCryptLib reference implementation.

Install

npm install ts-aes-cbc

Usage

import { aesCbcEncrypt, aesCbcDecrypt, AesCbcEncryptor } from 'ts-aes-cbc';

// One-shot
const key = new Uint8Array(16);   // 16, 24, or 32 bytes
const iv  = new Uint8Array(16);   // 16-byte IV
const pt  = new Uint8Array(32);   // multiple of 16 bytes (no padding applied)
const ct  = aesCbcEncrypt(key, iv, pt);
const out = aesCbcDecrypt(key, iv, ct);

// Streaming
const enc = new AesCbcEncryptor(key, iv);
const part1 = enc.encrypt(pt.slice(0, 16));
const part2 = enc.encrypt(pt.slice(16));

API surface

  • aesCbcEncrypt(key, iv, plaintext): Uint8Array — one-shot. Lengths must be multiples of 16.
  • aesCbcDecrypt(key, iv, ciphertext): Uint8Array — one-shot.
  • class AesCbcEncryptor — streaming API with .encrypt(chunk) / .decrypt(chunk) (each chunk must be a multiple of 16 bytes).
  • AES_BLOCK_SIZE = 16 — exported constant.

Reference vectors

The test suite asserts against:

| Spec | Key | Pass | |---|---|---| | NIST SP 800-38A §F.2.1 | AES-128 | ✓ | | NIST SP 800-38A §F.2.3 | AES-192 | ✓ | | NIST SP 800-38A §F.2.5 | AES-256 | ✓ |

Plus CBC-mode invariants (identical plaintext blocks produce distinct ciphertext blocks) and streaming-matches-one-shot.

Run:

npm test

Caveats

  • No padding. Plaintext/ciphertext lengths must be multiples of 16 bytes. Pad with PKCS#7 yourself (or use a higher-level construction that includes padding).
  • No authentication. CBC alone is malleable — bit-flips in the ciphertext predictably flip bits in the next block of plaintext. For real-world use, pair with HMAC (encrypt-then-MAC) or use an AEAD construction (AES-GCM, ChaCha20-Poly1305).
  • IV must be unpredictable. Reusing IVs reveals plaintext patterns. Generate a fresh random IV per encryption with crypto.getRandomValues(new Uint8Array(16)).
  • Padding-oracle attacks. If you accept ciphertext from untrusted sources and react differently to padding errors, you're vulnerable. Use AEAD (AES-GCM) for new code.
  • Not constant-time. Direct reference translation; JS runtime adds further timing variability.

License

Unlicense / public domain. Original C by WaterJuice under Unlicense.

See also

  • ts-wjcryptlib-aes — the AES core this CBC builds on
  • ts-tiny-aes — alternative AES port (smaller, compile-time variant)
  • ts-xtea — XTEA block cipher with built-in CBC
  • cpp-to-ts — the translator that produced this package