Skip to content

Instantly share code, notes, and snippets.

@SergioLarios
Created April 20, 2017 12:57
Show Gist options
  • Save SergioLarios/48dca687aba0073d73173f4c2aedf22e to your computer and use it in GitHub Desktop.
Save SergioLarios/48dca687aba0073d73173f4c2aedf22e to your computer and use it in GitHub Desktop.
import { pbkdf2, randomBytes } from "crypto";
/**
* Interface with all the necessary items related to the encryption
*/
export interface IEncryptedPassord {
encryptedPassword: string;
salt: string;
iterations: number;
}
/**
* Utils class to handle common operations to authenticate such as encrypt or decrypt a password
*/
export class AuthUtils {
// --------------------------------------------------------
// --------------------- Public methods -------------------
// --------------------------------------------------------
/**
* Encrypts the given password with hmac sha512, a 32bit salt and 20000 iterations and returns an object with:
* the result hash, the used salt and the number of iterations made
* @param password
*/
public static encryptPassword(password: string): Promise<IEncryptedPassord> {
let salt = randomBytes(this.SALT_BYTES).toString(this.STRING_GENERATOR);
return this.encrypt(password, salt, this.ITERATIONS);
}
/**
* Checks if the given password matches the stored one
* @param password
* @param storedPassword
*/
public static checkPassword(password:string, storedPassword:IEncryptedPassord): Promise<boolean> {
return this.encrypt(password, storedPassword.salt, storedPassword.iterations).then((resultEnc)=> {
return resultEnc.encryptedPassword === storedPassword.encryptedPassword;
}).catch((err) => {
console.log(err);
return false;
});
}
// --------------------------------------------------------
// -------------------- Private methods -------------------
// --------------------------------------------------------
/**
* Encrypts the given password with the salt and iterations provided
* @param password
* @param salt
* @param iterations
*/
private static encrypt(password: string, salt: string, iterations: number): Promise<IEncryptedPassord> {
return new Promise<IEncryptedPassord>((resolve, reject) => {
pbkdf2(password, salt, iterations, this.KEYLEN, this.DIGEST, (err, key) => {
if (err) { reject(err) }
else {
let result: IEncryptedPassord = {
encryptedPassword: key.toString(this.STRING_GENERATOR),
iterations: iterations,
salt: salt
};
resolve(result);
}
});
});
}
// --------------------------------------------------------
// ------------------- Private constants ------------------
// --------------------------------------------------------
private static readonly ITERATIONS: number = 20000;
private static readonly SALT_BYTES: number = 32;
private static readonly STRING_GENERATOR: string = 'hex';
private static readonly KEYLEN: number = 512;
private static readonly DIGEST: string = 'sha512';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment