1.0.1 • Published 3 years ago

@spaceaardvark/encrypt v1.0.1

Weekly downloads
-
License
MIT
Repository
github
Last release
3 years ago

Build Status

Encrypt

Encrypt and decrypt strings with a minimal interface. Designed for encrypting sensitive strings and files with cryptographic best practices.

Features

:heavy_check_mark: Best practice cryptography.
:heavy_check_mark: Simple API.
:heavy_check_mark: ES6 modules.
:heavy_check_mark: No dependencies.
:heavy_check_mark: Functional- and curry-friendly (data parameters last).
:heavy_check_mark: 100% unit test coverage.
:heavy_check_mark: Backward-compatible encryption.

Install

Requires Node.js v14 or higher.

$ npm install --save @spaceaardvark/encrypt
$ yarn add @spaceaardvark/encrypt

Usage

import { encrypt, decrypt } from "@spaceaardvark/encrypt";

let password, text, encrypted;

password = "Check under the couch cushion.";
text = "I found my purpose.";

encrypted = await encrypt(password, text);
decrypted = await decrypt(password, encrypted);  // I found my purpose.

Cryptography

  • Key derivation function (KDF): PBKDF2, SHA256, crypto.pbkdf2()
  • Salt: random, crypto.randomBytes()
  • Iterations: customizable, default is 5,000 (see next section)
  • Cipher algorithm: AES-256-CBC, crypto.createCipheriv()
  • Initialization vector: random, crypto.randomBytes()
  • Encrypted format: kdf(params):cipher(params):payload

The password is combined with a random salt to produce a key. The key is combined with a random initialization vector to produce the encrypted text. The final, encrypted text is prefixed with the algorithm parameters for reliable, backward-compatible decryption. (The parameters included in the encrypted format are "public" and do not compromise the strength of the encryption.)

Iterations

The strength of the encryption is largely determined by the number of iterations used to transform the password into a cryptographic key. Generating the key over and over is called key stretching and is discussed at length here.

The encrypt() function uses 5,000 iterations. You can adjust this number by calling encryptIterations() instead.

IterationsEncryption speedDictionary and brute-force attacks
:arrow_up: higher:snail: slower:lock: decreases vulnerability
:arrow_down: lower:zap: faster:warning: increases vulnerability

How many iterations should you use? As many as you can without creating (1) a negative user experience and/or (2) unacceptable strain on your hardware. Run tests on your production hardware to find the right threshold.

API


encrypt(password: string, text: string): Promise<string>

Encrypts a string with a password.

password: plain text password

text: plain text to encrypt

returns: Promise that resolves to encrypted text (with encryption parameters prefixed)


encryptIterations(password: string, iterations: number, text: string): Promise<string>

Encrypts a string with a password and a custom number of key derivation iterations.

password: plain text password

iterations: number of iterations to generate the key

text: plain text to encrypt

returns: Promise that resolves to encrypted text (with encryption parameters prefixed)


decrypt(password: string, encrypted: string): Promise<string>

Decrypts an encrypted string produced by encrypt().

password: plain text password

encrypted: string produced by encrypt()

returns: Promise that resolves to the plain text originally passed to encrypt()


Contributing

Be sure to create an issue before you submit a change request. Requests to expand the minimal interface will be politely and graciously declined, but anything else is fair game.

The library does not require a build step and is easy to test. See the scripts section in package.json for more information.