NoCache

Table of Contents

Build a Cryptographically-Secure Password Generator in Node.js with TypeScript

Cyrus Kao
Last modified on .

I wrote a dead simple JavaScript library called pswd-generator to generate passwords for this blog. In just 23 lines of code, I was able to build a cryptographically-secure password generator thanks to Node.js's native crypto module. And this guide will show you how it's done with TypeScript.

Build Your Own Password Generator

Follow this section to write your own password generator, or to use the library directly.

Import crypto module

First import the crypto module from Node.js:

import crypto from 'crypto';
TypeScript

Add Type Declarations

If your IDE shows the error Cannot find module 'crypto' or its corresponding type declarations., install the typings of Node.js would resolve this error:

$ npm i -D @types/node

Ignore this part if not using TypeScript.

Define Charsets

Then, start by creating some charsets for our password generation:

const charsets = {
	NUMBERS: '0123456789',
	LOWERCASE: 'abcdefghijklmnopqrstuvwxyz',
	UPPERCASE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
	SYMBOLS: '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~',
};
TypeScript

Main Code

Create a function that takes two parameters, length and charset, use crypto.randomInt with chartsetLength to get a random charset index (0 <= index < chartsetLength) then append the character to password until the target length is satisfied:

function generatePassword(
	length: number,
	charset: string,
): string {
	// calculate length of charset beforehand for performance
	const charsetLength = charset.length;

	let password = '';

	// add characters to `password` until desired length is reached
	while (length--) {
		// use `crypto.randomInt` to generate cryptographically-secure random number as charset index
		password += charset[crypto.randomInt(charsetLength)];
	}

	return password;
}
TypeScript

Be aware crypto.randomInt takes a max range of 2^48 - 1, although it is very unlikely your charset exceed that length:

crypto.randomInt
Documentation of crypto.randomInt

Usage

Generate a 24 characters password with the charset ABCDEFG:

generatePassword(24, 'ABCDEFG');
TypeScript

Use Presets

Generate a 24 characters password with all preset charsets combined:

generatePassword(24, charsets.NUMBERS + charsets.LOWERCASE + charsets.UPPERCASE + charsets.SYMBOLS);
TypeScript

Full Example

Module

password.tsimport crypto from 'crypto';

export const charsets = {
  NUMBERS: '0123456789',
  LOWERCASE: 'abcdefghijklmnopqrstuvwxyz',
  UPPERCASE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
  SYMBOLS: '!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~',
};

export default function generatePassword(
  length: number,
  charset: string,
): string {
  const charsetLength = charset.length;

  let password = '';

  while (length--) {
    password += charset[crypto.randomInt(charsetLength)];
  }

  return password;
}
TypeScript

App

index.tsimport generatePassword, { charsets } from './password';

const password = generatePassword(24, charsets.NUMBERS + charsets.LOWERCASE + charsets.UPPERCASE + charsets.SYMBOLS);

console.log(password);
TypeScript
A:_X`h%&:eto5d8i?bFZmOAU
Output

Use Directly

To use the password generator without building your own, install pswd-generator from npm:

$ npm i pswd-generator

Then import pswd-generator and it's ready to use:

import generatePassword, { charsets } from 'pswd-generator';

const password = generatePassword(24, charsets.NUMBERS + charsets.LOWERCASE + charsets.UPPERCASE + charsets.SYMBOLS);

console.log(password);
TypeScript
A:_X`h%&:eto5d8i?bFZmOAU
Output

Comments

Sign in to leave a comment.