Created
April 20, 2017 12:57
-
-
Save SergioLarios/48dca687aba0073d73173f4c2aedf22e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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