UNPKG

fortify2-js

Version:

MOST POWERFUL JavaScript Security Library! Military-grade cryptography + 19 enhanced object methods + quantum-resistant algorithms + perfect TypeScript support. More powerful than Lodash with built-in security.

317 lines (314 loc) 9.06 kB
import { KeyDerivationHashFunction, RuntimeEnvironment, KeyDerivationAlgorithm } from './keys-types.js'; import { keyLogger } from './keys-logger.js'; /** * Key Derivation Utilities * Helper functions and utilities for key derivation operations */ /** * Environment detection and capability assessment */ class EnvironmentDetector { /** * Detect runtime environment and capabilities */ static detect() { if (this.cachedInfo) { return this.cachedInfo; } const info = { type: this.detectEnvironmentType(), hasNodeCrypto: this.hasNodeCrypto(), hasWebCrypto: this.hasWebCrypto(), hasWorkerSupport: this.hasWorkerSupport(), availableLibraries: this.detectAvailableLibraries(), capabilities: { pbkdf2: false, scrypt: false, argon2: false, }, }; // Detect algorithm capabilities info.capabilities.pbkdf2 = this.canUsePBKDF2(); info.capabilities.scrypt = this.canUseScrypt(); info.capabilities.argon2 = this.canUseArgon2(); this.cachedInfo = info; keyLogger.logEnvironmentDetection(info.type, info); return info; } static detectEnvironmentType() { if (typeof window !== "undefined") { if (typeof globalThis.importScripts === "function") { return RuntimeEnvironment.WEB_WORKER; } return RuntimeEnvironment.BROWSER; } if (typeof process !== "undefined" && process.versions?.node) { return RuntimeEnvironment.NODE_JS; } return RuntimeEnvironment.UNKNOWN; } static hasNodeCrypto() { try { return (typeof require === "function" && typeof require("crypto") !== "undefined"); } catch { return false; } } static hasWebCrypto() { return (typeof crypto !== "undefined" && typeof crypto.subtle !== "undefined"); } static hasWorkerSupport() { return typeof Worker !== "undefined"; } static detectAvailableLibraries() { const libraries = []; const testLibraries = [ "pbkdf2", "scrypt-js", "argon2", "argon2-browser", ]; for (const lib of testLibraries) { try { if (typeof require === "function") { require(lib); libraries.push(lib); } } catch { // Library not available } } return libraries; } static canUsePBKDF2() { return this.hasNodeCrypto() || this.hasWebCrypto(); } static canUseScrypt() { try { if (this.hasNodeCrypto()) { const crypto = require("crypto"); return typeof crypto.scryptSync === "function"; } return false; } catch { return false; } } static canUseArgon2() { try { if (typeof require === "function") { require("argon2"); return true; } return false; } catch { return false; } } /** * Clear cached environment info (for testing) */ static clearCache() { this.cachedInfo = null; } } EnvironmentDetector.cachedInfo = null; /** * Input validation utilities */ class ValidationUtils { /** * Validate key derivation algorithm */ static validateAlgorithm(algorithm) { const normalizedAlgorithm = algorithm.toLowerCase(); switch (normalizedAlgorithm) { case "pbkdf2": return KeyDerivationAlgorithm.PBKDF2; case "scrypt": return KeyDerivationAlgorithm.SCRYPT; case "argon2": case "argon2id": return KeyDerivationAlgorithm.ARGON2ID; case "argon2i": return KeyDerivationAlgorithm.ARGON2I; case "argon2d": return KeyDerivationAlgorithm.ARGON2D; default: throw new Error(`Unsupported algorithm: ${algorithm}`); } } /** * Validate hash function */ static validateHashFunction(hashFunction) { const normalized = hashFunction.toLowerCase(); switch (normalized) { case "sha256": return KeyDerivationHashFunction.SHA256; case "sha512": return KeyDerivationHashFunction.SHA512; case "sha3-256": return KeyDerivationHashFunction.SHA3_256; case "sha3-512": return KeyDerivationHashFunction.SHA3_512; default: throw new Error(`Unsupported hash function: ${hashFunction}`); } } /** * Validate iterations parameter */ static validateIterations(iterations, min = 1000, max = 10000000) { if (!Number.isInteger(iterations) || iterations < min || iterations > max) { throw new Error(`Iterations must be an integer between ${min} and ${max}`); } return iterations; } /** * Validate key length */ static validateKeyLength(keyLength, min = 16, max = 128) { if (!Number.isInteger(keyLength) || keyLength < min || keyLength > max) { throw new Error(`Key length must be an integer between ${min} and ${max} bytes`); } return keyLength; } /** * Validate salt */ static validateSalt(salt) { if (salt === undefined) { return undefined; } if (typeof salt === "string") { if (salt.length < 8) { throw new Error("Salt string must be at least 8 characters long"); } return new TextEncoder().encode(salt); } if (salt instanceof Uint8Array) { if (salt.length < 8) { throw new Error("Salt must be at least 8 bytes long"); } return salt; } throw new Error("Salt must be a string or Uint8Array"); } } /** * Data conversion utilities */ class ConversionUtils { /** * Convert input to Uint8Array */ static toUint8Array(input) { if (typeof input === "string") { return new TextEncoder().encode(input); } return input; } /** * Convert Uint8Array to hex string */ static toHexString(bytes) { return Array.from(bytes) .map((byte) => byte.toString(16).padStart(2, "0")) .join(""); } /** * Convert hex string to Uint8Array */ static fromHexString(hex) { if (hex.length % 2 !== 0) { throw new Error("Invalid hex string length"); } const bytes = new Uint8Array(hex.length / 2); for (let i = 0; i < hex.length; i += 2) { bytes[i / 2] = parseInt(hex.substring(i, i + 2), 16); } return bytes; } /** * Secure memory wipe */ static secureWipe(buffer) { if (buffer && buffer.fill) { buffer.fill(0); } } } /** * Performance measurement utilities */ class PerformanceUtils { /** * Measure execution time of a function */ static async measureTime(fn) { const start = performance.now(); const result = await fn(); const time = performance.now() - start; return { result, time }; } /** * Estimate memory usage (approximate) */ static estimateMemoryUsage(data) { if (typeof data === "string") { return data.length * 2; // UTF-16 encoding } if (data instanceof Uint8Array) { return data.length; } if (typeof data === "object" && data !== null) { return JSON.stringify(data).length * 2; } return 0; } /** * Create a timeout promise */ static timeout(promise, ms) { return Promise.race([ promise, new Promise((_, reject) => setTimeout(() => reject(new Error(`Operation timed out after ${ms}ms`)), ms)), ]); } } /** * Algorithm-specific constants and defaults */ const ALGORITHM_DEFAULTS = { PBKDF2: { iterations: 100000, keyLength: 32, hashFunction: KeyDerivationHashFunction.SHA256, }, SCRYPT: { cost: 14, // N = 2^14 = 16384 blockSize: 8, parallelization: 1, keyLength: 32, }, ARGON2: { timeCost: 3, memoryCost: 4096, // 4MB parallelism: 1, keyLength: 32, variant: "argon2id", }, }; export { ALGORITHM_DEFAULTS, ConversionUtils, EnvironmentDetector, PerformanceUtils, ValidationUtils }; //# sourceMappingURL=keys-utils.js.map