@web5/agent
Version:
85 lines • 4.49 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
// ! TODO : Make sure I remove `@noble/ciphers` from the Agent package.json once this is moved to the `@web5/crypto` package.
import { getWebcryptoSubtle } from '@noble/ciphers/webcrypto';
/**
* The `Pbkdf2` class provides a secure way to derive cryptographic keys from a password
* using the PBKDF2 (Password-Based Key Derivation Function 2) algorithm.
*
* The PBKDF2 algorithm is widely used for generating keys from passwords, as it applies
* a pseudorandom function to the input password along with a salt value and iterates the
* process multiple times to increase the key's resistance to brute-force attacks.
*
* Notes:
* - The `baseKeyBytes` that will be the input key material for PBKDF2 is expected to be a low-entropy
* value, such as a password or passphrase. It should be kept confidential.
* - In 2023, {@link https://web.archive.org/web/20230123232056/https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2 | OWASP recommended}
* a minimum of 600,000 iterations for PBKDF2-HMAC-SHA256 and 210,000 for PBKDF2-HMAC-SHA512.
*
* @example
* ```ts
* // Key Derivation
* const derivedKeyBytes = await Pbkdf2.deriveKeyBytes({
* baseKeyBytes: new TextEncoder().encode('password'), // The password as a Uint8Array
* hash: 'SHA-256', // The hash function to use ('SHA-256', 'SHA-384', 'SHA-512')
* salt: new Uint8Array([...]), // The salt value
* iterations: 600_000, // The number of iterations
* length: 256 // The length of the derived key in bits
* });
* ```
*
* @remarks
* This class relies on the availability of the Web Crypto API.
*/
export class Pbkdf2 {
/**
* Derives a cryptographic key from a password using the PBKDF2 algorithm.
*
* @remarks
* This method applies the PBKDF2 algorithm to the provided password along with
* a salt value and iterates the process a specified number of times. It uses
* a cryptographic hash function to enhance security and produce a key of the
* desired length. The method is capable of utilizing either the Web Crypto API
* or the Node.js Crypto module, depending on the environment's support.
*
* @example
* ```ts
* const derivedKeyBytes = await Pbkdf2.deriveKeyBytes({
* baseKeyBytes: new TextEncoder().encode('password'), // The password as a Uint8Array
* hash: 'SHA-256', // The hash function to use ('SHA-256', 'SHA-384', 'SHA-512')
* salt: new Uint8Array([...]), // The salt value
* iterations: 600_000, // The number of iterations
* length: 256 // The length of the derived key in bits
* });
* ```
*
* @param params - The parameters for key derivation.
* @returns A Promise that resolves to the derived key as a byte array.
*/
static deriveKeyBytes({ baseKeyBytes, hash, salt, iterations, length }) {
return __awaiter(this, void 0, void 0, function* () {
// Get the Web Crypto API interface.
const webCrypto = getWebcryptoSubtle();
// Import the password as a raw key for use with the Web Crypto API.
const webCryptoKey = yield webCrypto.importKey('raw', // key format is raw bytes
baseKeyBytes, // key data to import
{ name: 'PBKDF2' }, // algorithm identifier
false, // key is not extractable
['deriveBits'] // key usages
);
// Derive the bytes using the Web Crypto API.
const derivedKeyBuffer = yield webCrypto.deriveBits({ name: 'PBKDF2', hash, salt, iterations }, webCryptoKey, length);
// Convert from ArrayBuffer to Uint8Array.
const derivedKeyBytes = new Uint8Array(derivedKeyBuffer);
return derivedKeyBytes;
});
}
}
//# sourceMappingURL=pbkdf2.js.map