@casual-simulation/crypto 3.1.14-alpha.3661157217 → 3.1.23-alpha.4227183169
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/HashHelpers.d.ts +12 -0
- package/HashHelpers.js +59 -9
- package/HashHelpers.js.map +1 -1
- package/package.json +2 -2
package/HashHelpers.d.ts
CHANGED
|
@@ -30,10 +30,22 @@ export declare function hashPassword(password: string): string;
|
|
|
30
30
|
export declare function verifyPassword(password: string, hash: string): boolean;
|
|
31
31
|
/**
|
|
32
32
|
* Hashes the given password using the given salt and returns the resulting base64 encoded hash.
|
|
33
|
+
*
|
|
34
|
+
* Returns a V1 hash that indicates that scrypt was used for the hashing process.
|
|
33
35
|
* @param password The password to hash.
|
|
34
36
|
* @param salt The salt to use for the password. Must be a base64 encoded string.
|
|
35
37
|
*/
|
|
36
38
|
export declare function hashPasswordWithSalt(password: string, salt: string): string;
|
|
39
|
+
/**
|
|
40
|
+
* Hashes the given password with the given salt using HMAC-SHA-256 and returns the resulting base64 encoded hash.
|
|
41
|
+
* This function is designed for high-entropy passwords (at least 128 bits of unguessable information) and is not designed
|
|
42
|
+
* for regular passwords. Use hashPasswordWithSalt() for regular low-entropy passwords.
|
|
43
|
+
*
|
|
44
|
+
* Returns a V2 hash that indicates that HMAC-SHA-256 was used for the hashing process.
|
|
45
|
+
* @param password The password that should be hashed.
|
|
46
|
+
* @param salt The salt to use for the password. Must be a base64 encoded string.
|
|
47
|
+
*/
|
|
48
|
+
export declare function hashHighEntropyPasswordWithSalt(password: string, salt: string): string;
|
|
37
49
|
/**
|
|
38
50
|
* Validates that the given password and salt match at least one of the given hashes.
|
|
39
51
|
* @param password The password to check.
|
package/HashHelpers.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { sha256 } from 'hash.js';
|
|
1
|
+
import { hmac, sha256 } from 'hash.js';
|
|
2
2
|
import stringify from 'fast-json-stable-stringify';
|
|
3
3
|
import { randomBytes } from 'tweetnacl';
|
|
4
4
|
import { deriveKey } from './Encryption';
|
|
@@ -83,6 +83,8 @@ export function verifyPassword(password, hash) {
|
|
|
83
83
|
}
|
|
84
84
|
/**
|
|
85
85
|
* Hashes the given password using the given salt and returns the resulting base64 encoded hash.
|
|
86
|
+
*
|
|
87
|
+
* Returns a V1 hash that indicates that scrypt was used for the hashing process.
|
|
86
88
|
* @param password The password to hash.
|
|
87
89
|
* @param salt The salt to use for the password. Must be a base64 encoded string.
|
|
88
90
|
*/
|
|
@@ -99,6 +101,30 @@ export function hashPasswordWithSalt(password, salt) {
|
|
|
99
101
|
const hashBytes = deriveKey(passwordBytes, saltBytes);
|
|
100
102
|
return `vH1.${fromByteArray(hashBytes.hash)}`;
|
|
101
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Hashes the given password with the given salt using HMAC-SHA-256 and returns the resulting base64 encoded hash.
|
|
106
|
+
* This function is designed for high-entropy passwords (at least 128 bits of unguessable information) and is not designed
|
|
107
|
+
* for regular passwords. Use hashPasswordWithSalt() for regular low-entropy passwords.
|
|
108
|
+
*
|
|
109
|
+
* Returns a V2 hash that indicates that HMAC-SHA-256 was used for the hashing process.
|
|
110
|
+
* @param password The password that should be hashed.
|
|
111
|
+
* @param salt The salt to use for the password. Must be a base64 encoded string.
|
|
112
|
+
*/
|
|
113
|
+
export function hashHighEntropyPasswordWithSalt(password, salt) {
|
|
114
|
+
if (!password) {
|
|
115
|
+
throw new Error('Invalid password. Must not be null or undefined.');
|
|
116
|
+
}
|
|
117
|
+
if (!salt) {
|
|
118
|
+
throw new Error('Invalid salt. Must not be null or undefined.');
|
|
119
|
+
}
|
|
120
|
+
const textEncoder = new TextEncoder();
|
|
121
|
+
const passwordBytes = textEncoder.encode(password);
|
|
122
|
+
const saltBytes = toByteArray(salt);
|
|
123
|
+
const h = hmac(sha256, saltBytes);
|
|
124
|
+
h.update(passwordBytes);
|
|
125
|
+
const hashBytes = new Uint8Array(h.digest());
|
|
126
|
+
return `vH2.${fromByteArray(hashBytes)}`;
|
|
127
|
+
}
|
|
102
128
|
/**
|
|
103
129
|
* Validates that the given password and salt match at least one of the given hashes.
|
|
104
130
|
* @param password The password to check.
|
|
@@ -115,19 +141,43 @@ export function verifyPasswordAgainstHashes(password, salt, hashes) {
|
|
|
115
141
|
if (!hashes) {
|
|
116
142
|
throw new Error('Invalid hashes. Must not be null or undefined.');
|
|
117
143
|
}
|
|
118
|
-
|
|
119
|
-
|
|
144
|
+
let version1Hashes = [];
|
|
145
|
+
let version2Hashes = [];
|
|
146
|
+
for (let hash of hashes) {
|
|
147
|
+
if (hash.startsWith('vH1.')) {
|
|
148
|
+
version1Hashes.push(hash);
|
|
149
|
+
}
|
|
150
|
+
else if (hash.startsWith('vH2.')) {
|
|
151
|
+
version2Hashes.push(hash);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (version1Hashes.length <= 0 && version2Hashes.length <= 0) {
|
|
120
155
|
throw new Error('Invalid hashes. Must contain at least one valid hash.');
|
|
121
156
|
}
|
|
122
157
|
const textEncoder = new TextEncoder();
|
|
123
158
|
const passwordBytes = textEncoder.encode(password);
|
|
124
159
|
const saltBytes = toByteArray(salt);
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
160
|
+
if (version2Hashes.length > 0) {
|
|
161
|
+
// Check version 2 hashes first since they are faster to compute.
|
|
162
|
+
const h = hmac(sha256, saltBytes);
|
|
163
|
+
h.update(passwordBytes);
|
|
164
|
+
const hashBytes = new Uint8Array(h.digest());
|
|
165
|
+
const hashBase64 = fromByteArray(hashBytes);
|
|
166
|
+
for (const hash of version2Hashes) {
|
|
167
|
+
const withoutVersion = hash.slice('vH2.'.length);
|
|
168
|
+
if (withoutVersion === hashBase64) {
|
|
169
|
+
return true;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
if (version1Hashes.length > 0) {
|
|
174
|
+
const passwordHash = deriveKey(passwordBytes, saltBytes);
|
|
175
|
+
const passwordHashBase64 = fromByteArray(passwordHash.hash);
|
|
176
|
+
for (const hash of version1Hashes) {
|
|
177
|
+
const withoutVersion = hash.slice('vH1.'.length);
|
|
178
|
+
if (withoutVersion === passwordHashBase64) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
131
181
|
}
|
|
132
182
|
}
|
|
133
183
|
return false;
|
package/HashHelpers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"HashHelpers.js","sourceRoot":"","sources":["HashHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"HashHelpers.js","sourceRoot":"","sources":["HashHelpers.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@casual-simulation/crypto",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.23-alpha.4227183169",
|
|
4
4
|
"description": "Crypto helpers used by AUX",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cryptography",
|
|
@@ -46,5 +46,5 @@
|
|
|
46
46
|
"scrypt-js": "3.0.1",
|
|
47
47
|
"tweetnacl": "1.0.3"
|
|
48
48
|
},
|
|
49
|
-
"gitHead": "
|
|
49
|
+
"gitHead": "b5a541f95bcfb41de2e2c2a04a5cff19d70ec09f"
|
|
50
50
|
}
|