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 🙏

© 2024 – Pkg Stats / Ryan Hefner

aes-ctr-concurrent

v1.0.0

Published

Native TypeScript Node.js library for AES-256-CTR, enabling concurrent encryption/decryption with precise IV offset handling down to any byte level, not just full blocks.

Readme

aes-ctr-concurrent

Native TypeScript Node.js library for AES-256-CTR, enabling concurrent encryption/decryption with precise IV offset handling down to any byte level, not just full blocks.

Features

  • Native implementation in TypeScript for Node.js
  • Utilizes native NodeJS's AES-256-CTR encryption and decryption (this library is just a wrapper for crypto module)
  • Concurrent operations with precise IV byte-offset handling
  • Promise-based API for modern asynchronous workflows
  • Flexible IV offset, allowing adjustments at any byte level

Installation

npm install aes-ctr-concurrent

Usage

Importing the Library

import { createCipher, createDecipher } from 'aes-ctr-concurrent';

Simple Encryption and Decryption

Here's a basic example of encrypting and decrypting data using the library (also see examples/simpleEncryptionAndDecryption.spec.ts):

import crypto from 'crypto';
import { createCipher, createDecipher } from 'aes-ctr-concurrent';

const key = crypto.randomBytes(32); // 32-byte key for AES-256
const iv = crypto.randomBytes(16);  // 16-byte IV for AES-CTR

const plaintext = Buffer.from('Hello, World!', 'utf-8');

// Encrypt
const cipher = createCipher(key, iv);
const encrypted = Buffer.concat([cipher.update(plaintext), cipher.final()]);

// Decrypt
const decipher = createDecipher(key, iv);
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);

console.log(decrypted.toString('utf-8')); // Outputs: Hello, World!

Advanced Example: Concurrent File Encryption with Streams

This example demonstrates how to encrypt a file concurrently by processing it in chunks and adjusting the IV offset precisely for each chunk. This allows for parallel processing of large files. You can also see examples/concurrentFileEncryption.spec.ts.

Setup

Ensure you have a file named plainTextFile that you want to encrypt and empty encryptedFile to which ecrypted data will be written.

import fs from 'fs/promises';
import crypto from 'crypto';
import { ReadStream, WriteStream, constants as fsConsts } from 'fs';
import { pipeline } from 'stream/promises';
import { createCipher } from 'aes-ctr-concurrent';

const key = crypto.randomBytes(32); // Your 32-byte encryption key
const iv = crypto.randomBytes(16);  // Your 16-byte initialization vector
const chunkLengthInBytes = 64 * 1024; // 64 KB chunks

async function encryptFileConcurrently() {
  const fileStats = await fs.stat('plainTextFile');
  const totalSize = fileStats.size;

  const encryptionPromises: Promise<void>[] = [];

  for (let offset = 0; offset < totalSize; offset += chunkLengthInBytes) {
    const encryptionPromise = encryptChunk(offset, chunkLengthInBytes);
    encryptionPromises.push(encryptionPromise);
  }

  await Promise.all(encryptionPromises);
  console.log('File encrypted successfully.');
}

async function encryptChunk(chunkStartPosition: number, chunkLength: number): Promise<void> {
  let fileReadHandle: fs.FileHandle | undefined;
  let fileWriteHandle: fs.FileHandle | undefined;
  let fileReadStream: ReadStream | undefined;
  let fileWriteStream: WriteStream | undefined;

  try {
    fileReadHandle = await fs.open('plainTextFile', fsConsts.O_RDONLY);
    fileWriteHandle = await fs.open('encryptedFile', fsConsts.O_WRONLY | fsConsts.O_CREAT);

    fileReadStream = fileReadHandle.createReadStream({
      start: chunkStartPosition,
      end: chunkStartPosition + chunkLength - 1,
    });

    fileWriteStream = fileWriteHandle.createWriteStream({
      start: chunkStartPosition,
    });

    const cipher = createCipher(key, iv, chunkStartPosition);

    await pipeline(fileReadStream, cipher, fileWriteStream);
  } catch (error) {
    console.error('Error encrypting chunk:', error);
  } finally {
    if (fileReadHandle) await fileReadHandle.close();
    if (fileWriteHandle) await fileWriteHandle.close();
    if (fileReadStream && !fileReadStream.destroyed) fileReadStream.destroy();
    if (fileWriteStream && !fileWriteStream.destroyed) fileWriteStream.destroy();
  }
}

encryptFileConcurrently();

API Reference

createCipher(key: Buffer, iv: Buffer, startPositionInBytes?: number | bigint): crypto.Cipher

Creates a crypto.Cipher instance for AES-256-CTR encryption.

  • Parameters:
    • key (Buffer): A 32-byte encryption key.
    • iv (Buffer): A 16-byte initialization vector.
    • startPositionInBytes (number | bigint, optional): Start position in bytes for the encryption process. Defaults to 0n.
  • Returns: crypto.Cipher instance.
  • Throws: AesCtrConcurrentError if parameters are invalid.

createDecipher(key: Buffer, iv: Buffer, startPositionInBytes?: number | bigint): crypto.Decipher

Creates a crypto.Decipher instance for AES-256-CTR decryption.

  • Parameters:
    • key (Buffer): A 32-byte encryption key.
    • iv (Buffer): A 16-byte initialization vector.
    • startPositionInBytes (number | bigint, optional): Start position in bytes for the decryption process. Defaults to 0n.
  • Returns: crypto.Decipher instance.
  • Throws: AesCtrConcurrentError if parameters are invalid.

Exceptions

AesCtrConcurrentError

Custom error class for handling exceptions within the library.

Additional Information

Why Use aes-ctr-concurrent?

Standard AES-CTR encryption increments the IV (Initialization Vector) automatically for each block of data (typically 16 bytes). However, when processing large files or data streams, it can be beneficial to encrypt/decrypt different parts of the data concurrently. This library allows you to:

  • Precisely Control IV Offsets: Adjust the IV to start encryption/decryption at any byte position, not just on block boundaries.
  • Enhance Performance: Process data in parallel, improving performance for large files.
  • Maintain Security: Ensures that the encryption remains secure by correctly handling IV adjustments.

How It Works

The library calculates the necessary IV adjustments based on the startPositionInBytes parameter. It:

  • Calculates how many full AES blocks are encompassed by the start position.
  • Increments the IV by the number of full blocks.
  • Adjusts the cipher stream to discard any bytes within the current block that precede the start position.

Acknowledgements

  • This library builds upon Node.js's native crypto module, extending its capabilities to support concurrent operations with precise IV management.