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

mail
Cyrus Kao
Last modified

I wrote a dead simple Javascript library called pswd-generator to generate password 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 wrote your own password generator, or to use the library directly.

Import crypto module

First import crypto module from Node.js:

import crypto from 'crypto';
TypeScript

Add Type Declarations

If 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
Bash

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

Create Function

Create a function that takes two parameters length and charset, use crypto.randomInt with chartsetLength to get random charset index (0 <= index < chartsetLength) then append the character to password until 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 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 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.ts

    import 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.ts

    import 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
Bash

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

0500