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

kaos

v2.0.0

Published

A simple stream encrypter

Downloads

7

Readme

Ϗɐ⊕𝕤

Kaos is a simple but efficient (and hopefully hard to break) data encrypter.

  • It is tiny with no dependencies
  • It implements Node.js' Transform streams
  • It enables encryption / decryption by chunks
  • Two consecutive encryptions with the same unsalted key generates different outputs

Important notes

  • The package is not backward compatible : files encrypted with one version must be decrypted with the exact same version
  • Specify the version during the installation, for instance : npm install [email protected]
  • When installed globally, it provides a command line :
    • kaos encrypt <path of file to encrypt> <path of encrypted file> <key>
    • kaos decrypt <path of the encrypted file> <path of decrypted file> <key>
    • The key can be either a string or the path to an existing file

API

Stream.Transform encrypt (key, offset = undefined)

The encrypt API accepts two parameters and returns a Stream.Transform instance.

The first parameter is the encryption key, it can be :

If an unsupported type is used an Error with the message Unsupported key type is thrown.

The second parameter must be used only when the encryption is done by chunks (see example).

// Simple encryption

const { promisify } = require('util')
const pipeline = promisify(require('stream').pipeline)
const { createReadStream, createWriteStream } = require('fs')
const { encrypt } = require('kaos')

pipeline(
  createReadStream('file to encrypt'),
  encrypt('my secret key'),
  createWriteStream('encrypted file')
)
  .then(() => console.log('Encryption succeeded.'))
  .catch(() => console.log('Encryption failed.'))

Encryption by chunks

If the data to encrypt is available by chunks (for instance : uploaded by packets), the same salted key must be used for all parts. The start offset of each chunk must be specified for all but the first one.

// Chunks encryption

const { promisify } = require('util')
const pipeline = promisify(require('stream').pipeline)
const { createReadStream, createWriteStream } = require('fs')
const { key, encrypt } = require('kaos')

const myKey = key('my secret key')

myKey.salt()
  // mySaltedKey must be reused for each chunks
  .then(mySaltedKey => pipeline(
    createReadStream('file to encrypt', { start: 0, end: 50 }),
    encrypt(mySaltedKey), // /!\ No offset fo the first chunk
    createWriteStream('encrypted file')
  ))
  .then(() => pipeline(
    createReadStream('file to encrypt', { start: 51 }),
    encrypt(mySaltedKey, 51), // Start offset of this chunk
    createWriteStream('encrypted file', { flags: 'a' })
  ))
  .then(() => console.log('Encryption succeeded.'))
  .catch(() => console.log('Encryption failed.'))

Stream.Transform decrypt (key, range = undefined)

The decrypt API accepts two parameters and returns a Stream.Transform instance.

The first parameter is the encryption key, similar to the encrypt API.

The second parameter must be used only when the decryption is done by chunks (see example).

NOTE : the decryption algorithm does not verify if the data is correctly decrypted.

// Simple decryption

const { promisify } = require('util')
const pipeline = promisify(require('stream').pipeline)
const { createReadStream, createWriteStream } = require('fs')
const { decrypt } = require('kaos')

pipeline(
  createReadStream('file to decrypt'),
  decrypt('my secret key'),
  createWriteStream('decrypted file')
)
  .then(() => console.log('Decryption succeeded.'))
  .catch(() => console.log('Decryption failed.'))

Decryption by chunks

When only a specific part of the message must be decoded, the key API provides information about the ranges to load from the encrypted data.

The first step consists in reading the key salt. Once salted, the key can be reused to decode other ranges of the same encrypted data.

// Chunks decryption

const { promisify } = require('util')
const pipeline = promisify(require('stream').pipeline)
const { createReadStream, createWriteStream } = require('fs')
const { key, decrypt } = require('kaos')

const myKey = key('my secret key')

myKey.saltRange()
  .then(range => myKey.salt(createReadStream('file to decrypt', range)))
  // To decode bytes between 1000 and 1100 (inclusively)
  .then(saltedKey => saltedKey.byteRange(1000, 1100))
  .then(range => pipeline(
    createReadStream('file to decrypt', range),
    decrypt(saltedKey, range),
    createWriteStream('decrypted byte range')
  ))
  .then(() => console.log('Decryption succeeded.'))
  .catch(() => console.log('Decryption failed.'))