@casual-simulation/crypto
Advanced tools
Comparing version 3.1.14-alpha.3661157217 to 3.1.23-alpha.4227183169
@@ -33,2 +33,4 @@ /// <reference types="node" /> | ||
* Hashes the given password using the given salt and returns the resulting base64 encoded hash. | ||
* | ||
* Returns a V1 hash that indicates that scrypt was used for the hashing process. | ||
* @param password The password to hash. | ||
@@ -39,2 +41,12 @@ * @param salt The salt to use for the password. Must be a base64 encoded string. | ||
/** | ||
* Hashes the given password with the given salt using HMAC-SHA-256 and returns the resulting base64 encoded hash. | ||
* This function is designed for high-entropy passwords (at least 128 bits of unguessable information) and is not designed | ||
* for regular passwords. Use hashPasswordWithSalt() for regular low-entropy passwords. | ||
* | ||
* Returns a V2 hash that indicates that HMAC-SHA-256 was used for the hashing process. | ||
* @param password The password that should be hashed. | ||
* @param salt The salt to use for the password. Must be a base64 encoded string. | ||
*/ | ||
export declare function hashHighEntropyPasswordWithSalt(password: string, salt: string): string; | ||
/** | ||
* Validates that the given password and salt match at least one of the given hashes. | ||
@@ -41,0 +53,0 @@ * @param password The password to check. |
@@ -1,2 +0,2 @@ | ||
import { sha256 } from 'hash.js'; | ||
import { hmac, sha256 } from 'hash.js'; | ||
import stringify from 'fast-json-stable-stringify'; | ||
@@ -86,2 +86,4 @@ import { randomBytes } from 'tweetnacl'; | ||
* Hashes the given password using the given salt and returns the resulting base64 encoded hash. | ||
* | ||
* Returns a V1 hash that indicates that scrypt was used for the hashing process. | ||
* @param password The password to hash. | ||
@@ -104,2 +106,26 @@ * @param salt The salt to use for the password. Must be a base64 encoded string. | ||
/** | ||
* Hashes the given password with the given salt using HMAC-SHA-256 and returns the resulting base64 encoded hash. | ||
* This function is designed for high-entropy passwords (at least 128 bits of unguessable information) and is not designed | ||
* for regular passwords. Use hashPasswordWithSalt() for regular low-entropy passwords. | ||
* | ||
* Returns a V2 hash that indicates that HMAC-SHA-256 was used for the hashing process. | ||
* @param password The password that should be hashed. | ||
* @param salt The salt to use for the password. Must be a base64 encoded string. | ||
*/ | ||
export function hashHighEntropyPasswordWithSalt(password, salt) { | ||
if (!password) { | ||
throw new Error('Invalid password. Must not be null or undefined.'); | ||
} | ||
if (!salt) { | ||
throw new Error('Invalid salt. Must not be null or undefined.'); | ||
} | ||
const textEncoder = new TextEncoder(); | ||
const passwordBytes = textEncoder.encode(password); | ||
const saltBytes = toByteArray(salt); | ||
const h = hmac(sha256, saltBytes); | ||
h.update(passwordBytes); | ||
const hashBytes = new Uint8Array(h.digest()); | ||
return `vH2.${fromByteArray(hashBytes)}`; | ||
} | ||
/** | ||
* Validates that the given password and salt match at least one of the given hashes. | ||
@@ -120,4 +146,13 @@ * @param password The password to check. | ||
} | ||
hashes = hashes.filter((h) => h.startsWith('vH1.')); | ||
if (hashes.length <= 0) { | ||
let version1Hashes = []; | ||
let version2Hashes = []; | ||
for (let hash of hashes) { | ||
if (hash.startsWith('vH1.')) { | ||
version1Hashes.push(hash); | ||
} | ||
else if (hash.startsWith('vH2.')) { | ||
version2Hashes.push(hash); | ||
} | ||
} | ||
if (version1Hashes.length <= 0 && version2Hashes.length <= 0) { | ||
throw new Error('Invalid hashes. Must contain at least one valid hash.'); | ||
@@ -128,12 +163,27 @@ } | ||
const saltBytes = toByteArray(salt); | ||
const passwordHash = deriveKey(passwordBytes, saltBytes); | ||
const passwordHashBase64 = fromByteArray(passwordHash.hash); | ||
for (const hash of hashes) { | ||
const withoutVersion = hash.slice('vH1.'.length); | ||
if (withoutVersion === passwordHashBase64) { | ||
return true; | ||
if (version2Hashes.length > 0) { | ||
// Check version 2 hashes first since they are faster to compute. | ||
const h = hmac(sha256, saltBytes); | ||
h.update(passwordBytes); | ||
const hashBytes = new Uint8Array(h.digest()); | ||
const hashBase64 = fromByteArray(hashBytes); | ||
for (const hash of version2Hashes) { | ||
const withoutVersion = hash.slice('vH2.'.length); | ||
if (withoutVersion === hashBase64) { | ||
return true; | ||
} | ||
} | ||
} | ||
if (version1Hashes.length > 0) { | ||
const passwordHash = deriveKey(passwordBytes, saltBytes); | ||
const passwordHashBase64 = fromByteArray(passwordHash.hash); | ||
for (const hash of version1Hashes) { | ||
const withoutVersion = hash.slice('vH1.'.length); | ||
if (withoutVersion === passwordHashBase64) { | ||
return true; | ||
} | ||
} | ||
} | ||
return false; | ||
} | ||
//# sourceMappingURL=HashHelpers.js.map |
{ | ||
"name": "@casual-simulation/crypto", | ||
"version": "3.1.14-alpha.3661157217", | ||
"version": "3.1.23-alpha.4227183169", | ||
"description": "Crypto helpers used by AUX", | ||
@@ -49,3 +49,3 @@ "keywords": [ | ||
}, | ||
"gitHead": "1a4688a5c80f36121fd0458346f944ea81fec2dd" | ||
"gitHead": "b5a541f95bcfb41de2e2c2a04a5cff19d70ec09f" | ||
} |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
79661
1330