1.0.1 • Published 5 years ago

instacrypt v1.0.1

Weekly downloads
1
License
MIT
Repository
github
Last release
5 years ago

npm GitHub last commit GitHub issues npm bundle size (minified + gzip) GitHub PRs Welcome Commitizen friendly

The problem

Encrypting and testing strings is hard, unless you want to dive head first into Node's crypto documentation

This solution

This simple class makes encrypting and testing strings a breeze. Create an encrypted string, and then check if it's a match against an unencrypted string with the built-in helpers. Perfect for storing sensitive-information like passwords that you don't need to know the value of.

It's just sugar on top of Node's built-in pbkdf2 and pbkdf2Sync functions to make your life easier.

There's also the option to pass in your own salt, iterations, algorithm and keylength values for full control of all the parameters. It's also made with TypeScript for awesome code completion and/or type checking if your using TypeScript or an editor with built-in support like VS Code.

What this plugin is not

  • A Cipher or decryption tool (once you create an encrypted string, you can only compare it to an unencrypted string to confirm that they match)

If you need something to actually decrypt (convert the encrypted string back to it's original, unencrypted string), check out something more powerful like Node's built-in Cipher.

This package is simply a much more pleasant way to use Node's built-in pbkdf2 and pbkdf2Sync functions, which is pretty damn secure for most applications.

Other solutions

Table of Contents

Installation

npm install instacrypt

Importing

Using CommonJS

const InstaCrypt = require('instacrypt');

Using ES6 Modules

import InstaCrypt from 'instacrypt';

Asynchronous usage

Using Promises

Create encrypted string

InstaCrypt()
	.toHash('my_password_string')
	.then((hashedPassword) => {
		// save to database, etc.
	});

Check if encrypted string matches unencrypted string

const userInputPassword = 'password1';
const hashedPassword = 'lkjl4j5lk2j4;l53j45lkjs;ldjflasfsd';

InstaCrypt().isMatch(userInputPassword, hashedPassword).then((result) => {
	result === true ? // login user, etc.
});

Using async/await

Create encrypted string

async function doSomethingWithHashedPasswordAsynchronously() {
	const hashedPassword = await InstaCrypt().toHash('my_password_string');
	// save to database, etc.
}

Check if encrypted string matches unencrypted string

const userInputPassword = 'password1';
const hashedPassword = 'lkjl4j5lk2j4;l53j45lkjs;ldjflasfsd';

async function authenticateUser(userInputPassword, hashedPassword) {
	const isAuthenticated = await InstaCrypt().isMatch(
		userInputPassword,
		hashedPassword,
	);

	isAuthenticated === true ? // login user, etc.
}

Synchronous examples

Create encrypted string

const hashedPassword = InstaCrypt().toHashSync('my_password_string');

Check if encrypted string matches unencrypted string

const userInputPassword = 'password1';
const hashedPassword = 'lkjl4j5lk2j4;l53j45lkjs;ldjflasfsd';

const isAuthenticated = InstaCrypt().isMatchSync(
	userInputPassword,
	hashedPassword,
);

Configuration

You can optionally pass in a configuration object for more control on the algorithmn, iterations, salt and key length.

Note: this example shows the default options.

InstaCrypt({
  salt: crypto.randomBytes(16)
  iterations: 1000,
  keyLength: 16,
  algorithm: 'sha512'
}).toHash(// etc...);

// or preferably for readability

const options = {
  salt: crypto.randomBytes(16)
  iterations: 1000,
  keyLength: 16,
  algorithm: 'sha512'
})

InstaCrypt(options).toHash(// etc...)

API

toHash(password: string): Promise<string>

Creates an encrypted string asynchronously (recommended for best performance).

isMatch(password: string, previouslyHashedPassword: string): Promise<boolean>

Checks if an unencrypted string matches an encrypted string asynchronously (recommended for the best performance).

toHashSync(password: string): string

Creates an encrypted string synchronously.

isMatchSync(password: string, previouslyHashedPassword: string): boolean

Checks if an unencrypted string matches an encrypted string synchronously.

config: Config

Optional configuration object to pass into the InstaCrypt instance

interface Config {
	salt?: Buffer;
	iterations?: number;
	keyLength?: number;
	algorithm?:
		| 'sha512'
		| 'RSA-MD4'
		| 'RSA-MD5'
		| 'RSA-MDC2'
		| 'RSA-RIPEMD160'
		| 'RSA-SHA1'
		| 'RSA-SHA1-2'
		| 'RSA-SHA224'
		| 'RSA-SHA256'
		| 'RSA-SHA384'
		| 'RSA-SHA512'
		| 'blake2b512'
		| 'blake2s256'
		| 'md4'
		| 'md4WithRSAEncryption'
		| 'md5'
		| 'md5-sha1'
		| 'md5WithRSAEncryption'
		| 'mdc2'
		| 'mdc2WithRSA'
		| 'ripemd'
		| 'ripemd160'
		| 'ripemd160WithRSA'
		| 'rmd160'
		| 'sha1'
		| 'sha1WithRSAEncryption'
		| 'sha224'
		| 'sha224WithRSAEncryption'
		| 'sha256'
		| 'sha256WithRSAEncryption'
		| 'sha384'
		| 'sha384WithRSAEncryption'
		| 'sha512'
		| 'sha512WithRSAEncryption'
		| 'ssl3-md5'
		| 'ssl3-sha1'
		| 'whirlpool';
}

FAQ

The asynchronous functions will not tie up your resources (i.e. block the event loop) while the encryption/checking is taking place, while the synchronous functions will.

For simple scripts, the synchronous versions are fine and easier to work with if you're not familiar with promises or async/await. For servers and performance-critical applications, we strongly recommend you use the asynchronous functions only.

Bcrypt and all of the other solutions are great!

This package is very easy to use like Bcrypt, but also gives you more flexibility on how many iterations, etc. so you can make it as intense/less intense as you need for your program and squeeze evry last drop of perfromance out of it based on your needs.

I haven't done any benchmarks yet, but it should be pretty fast since it's just sugar on Node's built in functions.

Plus, it's extremely lightweight and you can read the souce code to see exactly what's going on and learn a little bit about crytography yourself.

License

MIT

Copyright 2018 Sean W. Lawrence - visit my portfolio