Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- var crypto = require('crypto');
- // NOTE: slower than 'bcrypt' but is pure JS and has no dependencies.
- // for server side, consider using 'bcrypt' (C++), has the same API.
- var bcrypt = require('bcryptjs');
- /* Applies SHA256 to the given data, returns encoded as base64 string.
- *
- * Parameters:
- * - data: any value usable by crypto's update() method, i.e: String
- * or buffer.
- *
- * Returns: String encoded as base64 of the sha256
- */
- function sha256AsBase64(data) {
- return crypto.createHash('sha256')
- .update(data)
- .digest('base64');
- }
- /* Get bcrypt salt from username.
- *
- * Parameters:
- * - `username`: string with username.
- * - `rounds` (optional): use bcrypt rounds, or 12 if omitted.
- * - `prefix` (optional): use bcrypt prefix, or `2a` if omitted.
- *
- * Returns: String encoded as bcrypt salt format. Example:
- * `$2a$12$N9qo8uLOickgx2ZMRZoMye`
- */
- function bcryptSaltFromUsername(username, rounds, prefix) {
- var hash = crypto.createHash('sha256').update(username).digest();
- return ('$' + (prefix || '2a') +
- '$' + (rounds || 12) +
- '$' + bcrypt.encodeBase64(hash, 16));
- }
- /* Hash the given password using the given salt.
- *
- * This basically calls bcrypt on the `sha256AsBase64(password)`.
- *
- * Parameters:
- * - `password`: string with clear text password.
- * - `salt`: salt encoded using bcrypt's standard format.
- *
- * Return: 60 characters string encoded with the standard bcrypt
- * format, ie:
- * `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
- */
- function bcryptPasswordSaltSync(password, salt) {
- return bcrypt.hashSync(sha256AsBase64(password), salt);
- }
- /* Create a `challenge` using the bcryptPassword and the given salt.
- *
- * This basically calls bcrypt on the `bcryptPassword`.
- *
- * Parameters:
- * - `bcryptPassword`: string with hashed password, see
- * `bcryptUserPasswordSync()`. Must be 60 characters in length.
- * - `salt`: salt encoded using bcrypt's standard format.
- *
- * Return: 60 characters string encoded with the standard bcrypt
- * format, ie:
- * `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
- */
- function bcryptChallengePasswordSync(bcryptPassword, salt) {
- if (bcryptPassword.length !== 60) {
- throw new Error('invalid bcryptPassword length!');
- }
- return bcrypt.hashSync(bcryptPassword, salt);
- }
- /* Given an username and its password, create the bcrypt hash expected
- * by Elo API.
- *
- * The Elo API demands 12 salt-rounds (2^12 operations = 4096
- * iterations) using the first 16 bytes of `salt16Bytes =
- * sha256(username)` encoded as `bcrypt.encodeBase64(salt16Bytes,
- * 16)`. **NOTE: bcrypt uses a custom base64 alphabet!**.
- *
- * Since bcrypt limits its hashed payload to 72 characters and
- * passwords are of an unknown size we apply `sha256AsBase64(password)`
- * so we're fixed to 44 characters resulting from the Base64 encode of
- * the 256 bits from sha256.
- *
- * The resulting string is a 60 characters string encoded with the
- * standard bcrypt format: a prefix, the salt-rounds, the salt and the
- * actual hash, Example:
- *
- * - Prefix: `2a` (bcrypt version)
- * - Rounds: `12`
- * - Salt: `N9qo8uLOickgx2ZMRZoMye`
- * - Hash: `IjZAgcfl7p92ldGxad68LJZdL17lhW`
- * - Encoded: `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
- *
- * Parameters:
- * - `username`: string with username.
- * - `password`: string with clear text password.
- *
- * Return: 60 characters string encoded with the standard bcrypt
- * format, ie:
- * `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
- */
- function bcryptUserPasswordSync(username, password) {
- var salt = bcryptSaltFromUsername(username);
- return bcryptPasswordSaltSync(password, salt);
- }
- /* Hash the given password using the given salt.
- *
- * This basically calls bcrypt on the `sha256AsBase64(password)`.
- *
- * Parameters:
- * - `password`: string with clear text password.
- * - `salt`: salt encoded using bcrypt's standard format.
- * - `cb`: the callback function that receives 2 parameters: error and
- * hash. It's called when the computation is done.
- *
- * Return: if no `cb` is provided, returns a `Promise`.
- */
- function bcryptPasswordSalt(password, salt, cb) {
- return bcrypt.hash(sha256AsBase64(password), salt, cb);
- }
- /* Create a `challenge` using the bcryptPassword and the given salt.
- *
- * This basically calls bcrypt on the `bcryptPassword`.
- *
- * Parameters:
- * - `bcryptPassword`: string with hashed password, see
- * `bcryptUserPassword()`. Must be 60 characters in length.
- * - `salt`: salt encoded using bcrypt's standard format.
- * - `cb`: the callback function that receives 2 parameters: error and
- * hash. It's called when the computation is done.
- *
- * Return: if no `cb` is provided, returns a `Promise`.
- */
- function bcryptChallengePassword(bcryptPassword, salt) {
- if (bcryptPassword.length !== 60) {
- throw new Error('invalid bcryptPassword length!');
- }
- return bcrypt.hash(bcryptPassword, salt);
- }
- /* Given an username and its password, create the bcrypt hash expected
- * by Elo API.
- *
- * The Elo API demands 12 salt-rounds (2^12 operations = 4096
- * iterations) using the first 16 bytes of `salt16Bytes =
- * sha256(username)` encoded as `bcrypt.encodeBase64(salt16Bytes,
- * 16)`. **NOTE: bcrypt uses a custom base64 alphabet!**.
- *
- * Since bcrypt limits its hashed payload to 72 characters and
- * passwords are of an unknown size we apply `sha256AsBase64(password)`
- * so we're fixed to 44 characters resulting from the Base64 encode of
- * the 256 bits from sha256.
- *
- * The resulting string is a 60 characters string encoded with the
- * standard bcrypt format: a prefix, the salt-rounds, the salt and the
- * actual hash, Example:
- *
- * - Prefix: `2a` (bcrypt version)
- * - Rounds: `12`
- * - Salt: `N9qo8uLOickgx2ZMRZoMye`
- * - Hash: `IjZAgcfl7p92ldGxad68LJZdL17lhW`
- * - Encoded: `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
- *
- * Parameters:
- * - `username`: string with username.
- * - `password`: string with clear text password.
- * - `cb`: the callback function that receives 2 parameters: error and
- * hash. It's called when the computation is done.
- *
- * Return: if no `cb` is provided, returns a `Promise`.
- */
- function bcryptUserPassword(username, password, cb) {
- var salt = bcryptSaltFromUsername(username);
- return bcryptPasswordSalt(password, salt, cb);
- }
- module.exports = {
- sha256AsBase64: sha256AsBase64,
- bcryptSaltFromUsername: bcryptSaltFromUsername,
- bcryptUserPasswordSync: bcryptUserPasswordSync,
- bcryptPasswordSaltSync: bcryptPasswordSaltSync,
- bcryptChallengePasswordSync: bcryptChallengePasswordSync,
- bcryptUserPassword: bcryptUserPassword,
- bcryptPasswordSalt: bcryptPasswordSalt,
- bcryptChallengePassword: bcryptChallengePassword,
- bcrypt: bcrypt,
- };
Add Comment
Please, Sign In to add comment