* Internally hashes a password. * @param {string} password Password to hash * @param {?string} salt Salt to use, actually never null * @param {function(Error, string=)=} callback Callback receiving the error, if any, and the resulting hash. If omitted, * hashing is performed synchronously. *
(password, salt, callback, progressCallback)
| 1033 | * @inner |
| 1034 | */ |
| 1035 | function _hash(password, salt, callback, progressCallback) { |
| 1036 | var err; |
| 1037 | if (typeof password !== "string" || typeof salt !== "string") { |
| 1038 | err = Error("Invalid string / salt: Not a string"); |
| 1039 | if (callback) { |
| 1040 | nextTick(callback.bind(this, err)); |
| 1041 | return; |
| 1042 | } else throw err; |
| 1043 | } |
| 1044 | |
| 1045 | // Validate the salt |
| 1046 | var minor, offset; |
| 1047 | if (salt.charAt(0) !== "$" || salt.charAt(1) !== "2") { |
| 1048 | err = Error("Invalid salt version: " + salt.substring(0, 2)); |
| 1049 | if (callback) { |
| 1050 | nextTick(callback.bind(this, err)); |
| 1051 | return; |
| 1052 | } else throw err; |
| 1053 | } |
| 1054 | if (salt.charAt(2) === "$") (minor = String.fromCharCode(0)), (offset = 3); |
| 1055 | else { |
| 1056 | minor = salt.charAt(2); |
| 1057 | if ( |
| 1058 | (minor !== "a" && minor !== "b" && minor !== "y") || |
| 1059 | salt.charAt(3) !== "$" |
| 1060 | ) { |
| 1061 | err = Error("Invalid salt revision: " + salt.substring(2, 4)); |
| 1062 | if (callback) { |
| 1063 | nextTick(callback.bind(this, err)); |
| 1064 | return; |
| 1065 | } else throw err; |
| 1066 | } |
| 1067 | offset = 4; |
| 1068 | } |
| 1069 | |
| 1070 | // Extract number of rounds |
| 1071 | if (salt.charAt(offset + 2) > "$") { |
| 1072 | err = Error("Missing salt rounds"); |
| 1073 | if (callback) { |
| 1074 | nextTick(callback.bind(this, err)); |
| 1075 | return; |
| 1076 | } else throw err; |
| 1077 | } |
| 1078 | var r1 = parseInt(salt.substring(offset, offset + 1), 10) * 10, |
| 1079 | r2 = parseInt(salt.substring(offset + 1, offset + 2), 10), |
| 1080 | rounds = r1 + r2, |
| 1081 | real_salt = salt.substring(offset + 3, offset + 25); |
| 1082 | password += minor >= "a" ? "\x00" : ""; |
| 1083 | |
| 1084 | var passwordb = utf8Array(password), |
| 1085 | saltb = base64_decode(real_salt, BCRYPT_SALT_LEN); |
| 1086 | |
| 1087 | /** |
| 1088 | * Finishes hashing. |
| 1089 | * @param {Array.<number>} bytes Byte array |
| 1090 | * @returns {string} |
| 1091 | * @inner |
| 1092 | */ |