Guest User

Untitled

a guest
Jun 23rd, 2018
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.63 KB | None | 0 0
  1. var crypto = require('crypto');
  2.  
  3. // NOTE: slower than 'bcrypt' but is pure JS and has no dependencies.
  4. // for server side, consider using 'bcrypt' (C++), has the same API.
  5. var bcrypt = require('bcryptjs');
  6.  
  7. /* Applies SHA256 to the given data, returns encoded as base64 string.
  8. *
  9. * Parameters:
  10. * - data: any value usable by crypto's update() method, i.e: String
  11. * or buffer.
  12. *
  13. * Returns: String encoded as base64 of the sha256
  14. */
  15. function sha256AsBase64(data) {
  16. return crypto.createHash('sha256')
  17. .update(data)
  18. .digest('base64');
  19. }
  20.  
  21. /* Get bcrypt salt from username.
  22. *
  23. * Parameters:
  24. * - `username`: string with username.
  25. * - `rounds` (optional): use bcrypt rounds, or 12 if omitted.
  26. * - `prefix` (optional): use bcrypt prefix, or `2a` if omitted.
  27. *
  28. * Returns: String encoded as bcrypt salt format. Example:
  29. * `$2a$12$N9qo8uLOickgx2ZMRZoMye`
  30. */
  31. function bcryptSaltFromUsername(username, rounds, prefix) {
  32. var hash = crypto.createHash('sha256').update(username).digest();
  33. return ('$' + (prefix || '2a') +
  34. '$' + (rounds || 12) +
  35. '$' + bcrypt.encodeBase64(hash, 16));
  36. }
  37.  
  38. /* Hash the given password using the given salt.
  39. *
  40. * This basically calls bcrypt on the `sha256AsBase64(password)`.
  41. *
  42. * Parameters:
  43. * - `password`: string with clear text password.
  44. * - `salt`: salt encoded using bcrypt's standard format.
  45. *
  46. * Return: 60 characters string encoded with the standard bcrypt
  47. * format, ie:
  48. * `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
  49. */
  50. function bcryptPasswordSaltSync(password, salt) {
  51. return bcrypt.hashSync(sha256AsBase64(password), salt);
  52. }
  53.  
  54. /* Create a `challenge` using the bcryptPassword and the given salt.
  55. *
  56. * This basically calls bcrypt on the `bcryptPassword`.
  57. *
  58. * Parameters:
  59. * - `bcryptPassword`: string with hashed password, see
  60. * `bcryptUserPasswordSync()`. Must be 60 characters in length.
  61. * - `salt`: salt encoded using bcrypt's standard format.
  62. *
  63. * Return: 60 characters string encoded with the standard bcrypt
  64. * format, ie:
  65. * `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
  66. */
  67. function bcryptChallengePasswordSync(bcryptPassword, salt) {
  68. if (bcryptPassword.length !== 60) {
  69. throw new Error('invalid bcryptPassword length!');
  70. }
  71. return bcrypt.hashSync(bcryptPassword, salt);
  72. }
  73.  
  74. /* Given an username and its password, create the bcrypt hash expected
  75. * by Elo API.
  76. *
  77. * The Elo API demands 12 salt-rounds (2^12 operations = 4096
  78. * iterations) using the first 16 bytes of `salt16Bytes =
  79. * sha256(username)` encoded as `bcrypt.encodeBase64(salt16Bytes,
  80. * 16)`. **NOTE: bcrypt uses a custom base64 alphabet!**.
  81. *
  82. * Since bcrypt limits its hashed payload to 72 characters and
  83. * passwords are of an unknown size we apply `sha256AsBase64(password)`
  84. * so we're fixed to 44 characters resulting from the Base64 encode of
  85. * the 256 bits from sha256.
  86. *
  87. * The resulting string is a 60 characters string encoded with the
  88. * standard bcrypt format: a prefix, the salt-rounds, the salt and the
  89. * actual hash, Example:
  90. *
  91. * - Prefix: `2a` (bcrypt version)
  92. * - Rounds: `12`
  93. * - Salt: `N9qo8uLOickgx2ZMRZoMye`
  94. * - Hash: `IjZAgcfl7p92ldGxad68LJZdL17lhW`
  95. * - Encoded: `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
  96. *
  97. * Parameters:
  98. * - `username`: string with username.
  99. * - `password`: string with clear text password.
  100. *
  101. * Return: 60 characters string encoded with the standard bcrypt
  102. * format, ie:
  103. * `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
  104. */
  105. function bcryptUserPasswordSync(username, password) {
  106. var salt = bcryptSaltFromUsername(username);
  107. return bcryptPasswordSaltSync(password, salt);
  108. }
  109.  
  110. /* Hash the given password using the given salt.
  111. *
  112. * This basically calls bcrypt on the `sha256AsBase64(password)`.
  113. *
  114. * Parameters:
  115. * - `password`: string with clear text password.
  116. * - `salt`: salt encoded using bcrypt's standard format.
  117. * - `cb`: the callback function that receives 2 parameters: error and
  118. * hash. It's called when the computation is done.
  119. *
  120. * Return: if no `cb` is provided, returns a `Promise`.
  121. */
  122. function bcryptPasswordSalt(password, salt, cb) {
  123. return bcrypt.hash(sha256AsBase64(password), salt, cb);
  124. }
  125.  
  126.  
  127. /* Create a `challenge` using the bcryptPassword and the given salt.
  128. *
  129. * This basically calls bcrypt on the `bcryptPassword`.
  130. *
  131. * Parameters:
  132. * - `bcryptPassword`: string with hashed password, see
  133. * `bcryptUserPassword()`. Must be 60 characters in length.
  134. * - `salt`: salt encoded using bcrypt's standard format.
  135. * - `cb`: the callback function that receives 2 parameters: error and
  136. * hash. It's called when the computation is done.
  137. *
  138. * Return: if no `cb` is provided, returns a `Promise`.
  139. */
  140. function bcryptChallengePassword(bcryptPassword, salt) {
  141. if (bcryptPassword.length !== 60) {
  142. throw new Error('invalid bcryptPassword length!');
  143. }
  144. return bcrypt.hash(bcryptPassword, salt);
  145. }
  146.  
  147. /* Given an username and its password, create the bcrypt hash expected
  148. * by Elo API.
  149. *
  150. * The Elo API demands 12 salt-rounds (2^12 operations = 4096
  151. * iterations) using the first 16 bytes of `salt16Bytes =
  152. * sha256(username)` encoded as `bcrypt.encodeBase64(salt16Bytes,
  153. * 16)`. **NOTE: bcrypt uses a custom base64 alphabet!**.
  154. *
  155. * Since bcrypt limits its hashed payload to 72 characters and
  156. * passwords are of an unknown size we apply `sha256AsBase64(password)`
  157. * so we're fixed to 44 characters resulting from the Base64 encode of
  158. * the 256 bits from sha256.
  159. *
  160. * The resulting string is a 60 characters string encoded with the
  161. * standard bcrypt format: a prefix, the salt-rounds, the salt and the
  162. * actual hash, Example:
  163. *
  164. * - Prefix: `2a` (bcrypt version)
  165. * - Rounds: `12`
  166. * - Salt: `N9qo8uLOickgx2ZMRZoMye`
  167. * - Hash: `IjZAgcfl7p92ldGxad68LJZdL17lhW`
  168. * - Encoded: `$2a$12$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy`
  169. *
  170. * Parameters:
  171. * - `username`: string with username.
  172. * - `password`: string with clear text password.
  173. * - `cb`: the callback function that receives 2 parameters: error and
  174. * hash. It's called when the computation is done.
  175. *
  176. * Return: if no `cb` is provided, returns a `Promise`.
  177. */
  178. function bcryptUserPassword(username, password, cb) {
  179. var salt = bcryptSaltFromUsername(username);
  180. return bcryptPasswordSalt(password, salt, cb);
  181. }
  182.  
  183. module.exports = {
  184. sha256AsBase64: sha256AsBase64,
  185. bcryptSaltFromUsername: bcryptSaltFromUsername,
  186. bcryptUserPasswordSync: bcryptUserPasswordSync,
  187. bcryptPasswordSaltSync: bcryptPasswordSaltSync,
  188. bcryptChallengePasswordSync: bcryptChallengePasswordSync,
  189. bcryptUserPassword: bcryptUserPassword,
  190. bcryptPasswordSalt: bcryptPasswordSalt,
  191. bcryptChallengePassword: bcryptChallengePassword,
  192. bcrypt: bcrypt,
  193. };
Add Comment
Please, Sign In to add comment