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

@sounisi5011/encrypted-archive

v0.1.0

Published

Convert data into a single encrypted archive data that contains all metadata needed for decryption

Downloads

137

Readme

@sounisi5011/encrypted-archive

Go to the latest release page on npm Supported Node.js version: ^12.17.x || 14.x || 15.x || 16.x || 17.x Tested with Jest Commitizen friendly Minified Bundle Size Details Install Size Details Dependencies Status Build Status Maintainability Status

Convert data into a single encrypted archive data that contains all metadata needed for decryption.

Features

  • Only password and target data are required

    Other data required for encryption (nonce, key derivation function, etc.) will be generated automatically.

  • Support for secure algorithms

    This package supports only the following algorithms that are currently (2021) recommended.

    • Encryption algorithm
      • AES-GCM (256-bit)
      • ChaCha20-Poly1305
    • Key derivation function
      • Argon2
  • A counter is used to generate the IV (Initialization Vector)

    When encrypting with the same key, the IV MUST NEVER be reused. However, there is a risk of generating the same IV when using random numbers. In this package, IVs are counter-generated to avoid unintentional reuse of IVs.

    See: nonce-disrespect/nonce-disrespect: Nonce-Disrespecting Adversaries: Practical Forgery Attacks on GCM in TLS

  • Backward compatibility

    The data format uses unsigned varint and Protocol Buffers. High backward compatibility is maintained even when new features are added in the future.

Example of use

  • Generating a backup file
  • Private data files accessible through public URLs

Not recommended for use

  • Encryption of transmission data

    If you encrypt a large amount of small data, there is a risk that the counter used to generate the IV will overflow.

  • Multi-processing and multi-threading

    Currently, the counter used to generate IVs does not support different processes or threads. If used in multiple processes or threads, there is a danger of duplicate IVs.

Attention

I am not a security expert. I have researched a lot of information in order to create this package. I believe that this package will be secure. However, there is a possibility that I am wrong.

Installation

npm install @sounisi5011/encrypted-archive
yarn add @sounisi5011/encrypted-archive
pnpm add @sounisi5011/encrypted-archive

Usage

Small data

If you have a short string or a small file of data to encrypt, you can use a simple function.

const { encrypt, decrypt } = require('@sounisi5011/encrypted-archive');

const cleartext = 'Hello World!';
const password = '1234';

encrypt(cleartext, password, {
    // These options are optional, but it is recommended that you specify the appropriate options for your application.
    algorithm: 'chacha20-poly1305',
    keyDerivation: {
        algorithm: 'argon2d',
        iterations: 3,
        memory: 12,
        parallelism: 1,
    },
    // If the data to be encrypted is text, you can also compress the data.
    // Binary data (e.g. images, videos, etc.) can also be compressed,
    // but the effect of compression is often small and is not recommended.
    compress: 'gzip',
})
    .then(encryptedData => {
        // ...
    })
    .catch(error => {
        // ...
    });

// ----- //

const encryptedData = Buffer.from( ... );
decrypt(encryptedData, password)
    .then(decryptedData => {
        // ...
    })
    .catch(error => {
        // ...
    });

Huge data

For huge files or data (e.g., hundreds of megabytes or tens of gigabytes), you can use Node.js Stream or Async Iteration.

Stream

const fs = require('fs');
const stream = require('stream');
const { encryptStream, decryptStream } = require('@sounisi5011/encrypted-archive');

const password = '1234';

const inputStream = fs.createReadStream('very-large.mp4');
const outputStream = fs.createWriteStream('very-large.mp4.enc');

stream.pipeline(
    inputStream,
    encryptStream(password, {
        // These options are optional, but it is recommended that you specify the appropriate options for your application.
        algorithm: 'aes-256-gcm',
        keyDerivation: {
            algorithm: 'argon2d',
            iterations: 3,
            memory: 12,
            parallelism: 1,
        },
        // If the data to be encrypted is text, you can also compress the data.
        // Binary data (e.g. images, videos, etc.) can also be compressed,
        // but the effect of compression is often small and is not recommended.
        //compress: 'gzip',
    }),
    outputStream,
    error => {
        if (error) {
            // ...
        } else {
            // ...
        }
    },
);

// ----- //

stream.pipeline(
    fs.createReadStream('very-large.mp4.enc'),
    decryptStream(password),
    fs.createWriteStream('very-large.mp4'),
    error => {
        if (error) {
            // ...
        } else {
            // ...
        }
    },
);

Async Iteration

const fs = require('fs');
const stream = require('stream');
const { encryptIterator, decryptIterator } = require('@sounisi5011/encrypted-archive');

const password = '1234';

const inputIterator = (async function*() {
    for await (const chunk of fs.createReadStream('very-large.mp4')) {
        yield chunk;
    }
})();
const encryptor = encryptIterator(password, {
    // These options are optional, but it is recommended that you specify the appropriate options for your application.
    algorithm: 'aes-256-gcm',
    keyDerivation: {
        algorithm: 'argon2d',
        iterations: 3,
        memory: 12,
        parallelism: 1,
    },
    // If the data to be encrypted is text, you can also compress the data.
    // Binary data (e.g. images, videos, etc.) can also be compressed,
    // but the effect of compression is often small and is not recommended.
    //compress: 'gzip',
});

(async () => {
    try {
        for await (const encryptedDataChunk of encryptor(inputIterator)) {
            // ...
        }
    } catch (error) {
        // ...
    }
})();

// ----- //

const inputEncryptedIterator = (async function*() {
    for await (const chunk of fs.createReadStream('very-large.mp4.enc')) {
        yield chunk;
    }
})();
const decryptor = decryptIterator(password);

(async () => {
    try {
        for await (const decryptedDataChunk of decryptor(inputEncryptedIterator)) {
            // ...
        }
    } catch (error) {
        // ...
    }
})();

API

encrypt(cleartext, password, options?)

Returns a Promise giving a Buffer object.

  • cleartext

    Type: string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer

  • password

    Type: string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer

  • options

    see EncryptOptions

decrypt(encryptedData, password)

Returns a Promise giving a Buffer object.

  • encryptedData

    Type: string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer

  • password

    Type: string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer

encryptStream(password, options?)

Returns a Transform stream.

  • password

    Type: string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer

  • options

    see EncryptOptions

decryptStream(password)

Returns a Transform stream.

  • password

    Type: string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer

encryptIterator(password, options?)

Returns an IteratorConverter function.

  • password

    Type: string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer

  • options

    see EncryptOptions

decryptIterator(password)

Returns an IteratorConverter function.

  • password

    Type: string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer

Returns an AsyncIterableIterator giving a Buffer object.

  • source

    Type:

      Iterable<string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer>
    | AsyncIterable<string | Buffer | TypedArray | DataView | ArrayBuffer | SharedArrayBuffer>

An object with the following properties:

All properties are optional.

Type: CryptoAlgorithmName

An encryption algorithm name string. Specify one of the following:

  • "aes-256-gcm"
  • "chacha20-poly1305" (default)

Type: KeyDerivationOptions

An object with the key derivation function name and options. The key derivation function name is specified as a string in the algorithm property. The other properties are options for the key derivation function.

Currently, the following key derivation functions are supported:

  • Argon2

    • algorithm

      • "argon2d" (default)
      • "argon2id"
    • iterations

      Type: number

      the number of iterations. default: 3

    • memory

      Type: number

      used memory, in KiB. default: 12

    • parallelism

      Type: number

      desired parallelism. default: 1

    For more information on the values that should be specified for these parameters, please refer to the following article: Choose Argon2 Parameters for Secure Password Hashing and Login - ory.sh

Type: CompressOptions | CompressOptions['algorithm']

A compression algorithm name string, or an options object for the compression algorithm. When specifying an object, the compression algorithm name is specified as a string in the algorithm property. The other properties are options for the compression algorithm.

Currently, the following compression algorithm are supported:

  • Gzip

    • algorithm
      • "gzip"

    Other properties are passed to zlib options. However, the following properties are not allowed:

    • flush
    • finishFlush
    • dictionary
    • info
    • maxOutputLength
  • Brotli

    • algorithm
      • "brotli"

    Other properties are passed to brotli options. However, the following properties are not allowed:

    • flush
    • finishFlush
    • maxOutputLength

Structure of the encrypted archive

see docs/encrypted-archive-structure.md