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

node-ciphers

v1.1.6

Published

A lightweight Node.js library for AES and DES encryption, offering flexible encoding options, support for various cipher modes, and seamless integration with streams.

Downloads

252

Readme

node-ciphers

npm version npm downloads codecov License FOSSA Status

A lightweight Node.js library for AES and DES encryption, offering flexible encoding options, support for various cipher modes, and seamless integration with streams.

Features

  • 🔒 AES and DES Encryption: Provides robust implementations for both AES and DES encryption algorithms, with support for various modes like CBC, CCM, and more
  • 🧰 Flexible Encoding Options: Customize encoding settings for encryption and decryption to suit your needs
  • 🔄 Encrypt and Decrypt JSON: Easily encrypt and decrypt JSON data directly, simplifying the handling of structured data
  • 📜 Mode Support: Includes CBC, CCM, CFB, CTR, ECB, GCM, and OFB modes
  • ⚙️ Stream Transformations: Seamlessly integrate with Node.js streams, allowing for encrypted data processing on-the-fly with transformation options
  • 🔑 Dynamic Key Handling: Automatically handles key lengths and their corresponding mode prefixes for both AES and DES, ensuring secure and correct key usage
  • 📂 Modular Architecture: Well-structured codebase with modular components, making it easy to extend and maintain

Environment Requirements

  • Node.js version 18 or higher

Installation

Add dependency (example using pnpm).

pnpm add node-ciphers

You can also use yarn, npm, or bun to add the dependency.

That's it! You're ready to use this package in your project. Check out the available ciphers and usage instructions below ✨.

Available Ciphers

AES

  • CBC
  • CCM
  • CFB
  • CFB1
  • CFB8
  • CTR
  • ECB
  • GCM
  • OFB

DES

  • CBC
  • CFB
  • CFB1
  • CFB8
  • ECB
  • OFB

Usage

AES

Below are examples of AES CBC and ECB encryption and decryption:

import { AESCipher } from 'node-ciphers';

const data = 'test';
const jsonData = { value: data };

// 128 bits cbc (16 bytes length key)
const cbcCipher = new AESCipher.CBC('0123456789abcdef');
console.log(cbcCipher.algorithm);
const cbcEncryptResult = cbcCipher.encrypt(data);
const cbcEncryptJsonResult = cbcCipher.encryptJSON(jsonData);
console.log(cbcEncryptResult);
console.log(cbcEncryptJsonResult);
if (!cbcEncryptResult || !cbcEncryptJsonResult) throw new Error('Encrypt failed');
console.log(cbcCipher.decrypt(cbcEncryptResult.data, cbcEncryptResult.iv));
console.log(cbcCipher.decryptToJSON(cbcEncryptJsonResult.data, cbcEncryptJsonResult.iv));

// 128 bits ecb (16 bytes length key)
const ecbCipher = new AESCipher.ECB('0123456789abcdef');
console.log(ecbCipher.algorithm);
const ecbEncryptResult = ecbCipher.encrypt(data);
const ecbEncryptJsonResult = ecbCipher.encryptJSON(jsonData);
console.log(ecbEncryptResult);
console.log(ecbEncryptJsonResult);
if (!ecbEncryptResult || !ecbEncryptJsonResult) throw new Error('Encrypt failed');
console.log(ecbCipher.decrypt(ecbEncryptResult.data));
console.log(ecbCipher.decryptToJSON(ecbEncryptJsonResult.data));

The cipher's encryption and decryption methods can be reused; there's no need to create a new one each time.

The encryption result is consistently an object with a data property containing the encrypted output and an iv property representing the randomly generated initialization vector (IV) for that encryption. To maintain a uniform structure, the iv property will still be included and return null in ECB mode, even though ECB does not use an IV.

AES encryption supports three key lengths: 128-bit, 192-bit, and 256-bit. These correspond to 16, 24, and 32 bytes, respectively.

When the provided key for creating a cipher is a string, it will be internally converted into a buffer and its byte length will be checked. The default encoding used for converting to a buffer is UTF-8, which may cause a difference between the character length and the byte length. To avoid errors, you can directly provide a key of the Buffer type when creating the cipher, or set the key option in the options parameter.

import { Buffer } from 'node:buffer';

// 192 bits cbc (24 bytes length key)
const cbcCipher192 = new AESCipher.CBC('😊😊😊😊😊😊😊😊😊😊😊😊', { key: 'ascii' });
console.log(cbcCipher192.algorithm); // aes-192-cbc

// 256 bits ecb (32 bytes length key)
const key = Buffer.from('😊😊😊😊😊😊😊😊', 'utf8');
const ecbCipher256 = new AESCipher.ECB(key);
console.log(ecbCipher256.algorithm); // aes-256-cbc

Some AES ciphers, such as CCM and GCM, require additional parameters during encryption and decryption.

[!IMPORTANT] In Node.js, the results of CFB, CFB1, and CFB8 encryption modes may differ from those in other programming languages due to differences in how the block size and feedback unit size are handled during encryption and decryption.

  • CFB Mode: Typically operates on a full block (often 128 bits) but allows for different feedback unit sizes (e.g., 1 bit, 8 bits, or 128 bits). This feedback size directly affects how the encryption and decryption processes are carried out.
  • CFB1, CFB8, and CFB: These modes use 1-bit, 8-bit, and full-block feedback sizes, respectively. The way these feedback sizes are implemented can vary across different programming languages or libraries, which may lead to different results even under the same conditions (e.g., same IV and key).

The key difference arises because of how the feedback block size is processed internally by different libraries, leading to potential inconsistencies in the encryption output.

DES

The usage is similar to AES, but the key's byte length corresponds to the following modes: 8 bytes (DES), 16 bytes (DES-EDE), and 24 bytes (DES-EDE3).

import { DESCipher } from 'node-ciphers';

const data = 'test';
const jsonData = { value: data };

// des-ede (16 bytes length key)
const cbcCipher = new DESCipher.CBC('0123456789abcdef');
console.log(cbcCipher.algorithm);
const cbcEncryptResult = cbcCipher.encrypt(data);
const cbcEncryptJsonResult = cbcCipher.encryptJSON(jsonData);
console.log(cbcEncryptResult);
console.log(cbcEncryptJsonResult);
if (!cbcEncryptResult || !cbcEncryptJsonResult) throw new Error('Encrypt failed');
console.log(cbcCipher.decrypt(cbcEncryptResult.data, cbcEncryptResult.iv));
console.log(cbcCipher.decryptToJSON(cbcEncryptJsonResult.data, cbcEncryptJsonResult.iv));

// des-ede3, 3des (24 bytes length key)
const ecbCipher = new DESCipher.ECB('0123456789abcdef01234567');
console.log(ecbCipher.algorithm);
const ecbEncryptResult = ecbCipher.encrypt(data);
const ecbEncryptJsonResult = ecbCipher.encryptJSON(jsonData);
console.log(ecbEncryptResult);
console.log(ecbEncryptJsonResult);
if (!ecbEncryptResult || !ecbEncryptJsonResult) throw new Error('Encrypt failed');
console.log(ecbCipher.decrypt(ecbEncryptResult.data));
console.log(ecbCipher.decryptToJSON(ecbEncryptJsonResult.data));

[!IMPORTANT] Standard DES mode (8-byte key length) has been disabled. Attempting to use it will result in an Invalid algorithm error. To enable it, you need to set the NODE_OPTIONS=--openssl-legacy-provider environment variable.

[!IMPORTANT] In the Bun, some ciphers or specific key lengths are currently unavailable.

Encoding

You can customize the data transformation encoding for encryption and decryption inputs and outputs.

// Create a cipher that outputs encryption results in Base64 and accepts encryption input in Base64 format
const cbcCipher = new AESCipher.CBC('0123456789abcdef', { decryptInput: 'base64', encryptOutput: 'base64' });

// Use hex output for this encryption only
cbcCipher.encrypt('test', { encryptOutput: 'hex' });

// Output the IV in Base64 format
cbcCipher.encrypt('test', { iv: 'base64' });

If the encrypted data cannot be decrypted, it may be due to not specifying the corresponding encoding. Please pay attention to encoding settings when using it. For default encoding values, refer to the BaseCipherEncodingOptions interface in this file.

License

MIT License

FOSSA Status