UNPKG

xypriss-security

Version:

XyPriss Security is an advanced JavaScript security library designed for enterprise applications. It provides military-grade encryption, secure data structures, quantum-resistant cryptography, and comprehensive security utilities for modern web applicatio

136 lines (132 loc) 5.3 kB
'use strict'; var keysLogger = require('../../keys-logger.js'); var keysTypes = require('../../keys-types.js'); var keysUtils = require('../../keys-utils.js'); var ScryptAlgo = require('./ScryptAlgo.js'); /** * Argon2 implementation with multiple backends */ class Argon2Algo { /** * Derive key using Argon2 with optimal backend selection */ static derive(password, salt, iterations, keyLength, variant = "argon2id") { const startTime = performance.now(); let backend; let key; let error; try { // Primary: Node.js argon2 library (if available) if (this.canUseArgon2Library()) { const result = this.deriveWithNodeLibrary(password, salt, iterations, keyLength, variant); backend = keysTypes.AlgorithmBackend.EXTERNAL_LIBRARY; key = result; keysLogger.keyLogger.debug("Argon2", "Using Node.js argon2 library"); } // Secondary: Browser argon2-browser (if available and has sync API) else if (this.canUseBrowserArgon2()) { const result = this.deriveWithBrowserLibrary(password, salt, iterations, keyLength, variant); backend = keysTypes.AlgorithmBackend.EXTERNAL_LIBRARY; key = result; keysLogger.keyLogger.debug("Argon2", "Using browser argon2 library"); } // Fallback: Scrypt with equivalent parameters else { keysLogger.keyLogger.warn("Argon2", "Argon2 not available, using Scrypt fallback"); const scryptCost = Math.min(18, Math.max(14, Math.floor(iterations / 2))); const scryptResult = ScryptAlgo.ScryptAlgo.derive(password, salt, scryptCost, keyLength); backend = keysTypes.AlgorithmBackend.PURE_JS; key = scryptResult.key; } } catch (err) { error = err instanceof Error ? err.message : "Unknown error"; throw err; } finally { const executionTime = performance.now() - startTime; const algorithm = variant === "argon2i" ? keysTypes.KeyDerivationAlgorithm.ARGON2I : variant === "argon2d" ? keysTypes.KeyDerivationAlgorithm.ARGON2D : keysTypes.KeyDerivationAlgorithm.ARGON2ID; const metrics = { algorithm, backend: backend, executionTime, memoryUsage: keysUtils.PerformanceUtils.estimateMemoryUsage(key), iterations, keyLength, success: !error, errorMessage: error, timestamp: Date.now(), }; keysLogger.keyLogger.logMetrics(metrics); return { key: key, backend: backend, metrics }; } } static canUseArgon2Library() { try { if (typeof require === "function") { const argon2 = require("argon2"); // Check if sync version is available (some versions have it) return (typeof argon2.hashSync === "function" || typeof argon2.hash === "function"); } return false; } catch { return false; } } static canUseBrowserArgon2() { try { if (typeof window !== "undefined" && typeof require === "function") { const argon2Browser = require("argon2-browser"); return typeof argon2Browser.hashSync === "function"; } return false; } catch { return false; } } static deriveWithNodeLibrary(password, salt, iterations, keyLength, variant) { const argon2 = require("argon2"); // Try sync version first if available if (typeof argon2.hashSync === "function") { const result = argon2.hashSync(Buffer.from(password), { type: argon2[variant] || argon2.argon2id, timeCost: iterations, memoryCost: 4096, parallelism: 1, salt: Buffer.from(salt), hashLength: keyLength, raw: true, }); return new Uint8Array(result); } // If no sync version, throw error to trigger fallback throw new Error("Argon2 sync API not available"); } static deriveWithBrowserLibrary(password, salt, iterations, keyLength, _variant) { const argon2Browser = require("argon2-browser"); // Only use if synchronous API is available if (typeof argon2Browser.hashSync === "function") { const result = argon2Browser.hashSync({ pass: password, salt: salt, time: iterations, mem: 4096, parallelism: 1, hashLen: keyLength, type: argon2Browser.ArgonType.Argon2id, }); return new Uint8Array(result.hash); } throw new Error("Browser Argon2 sync API not available"); } } exports.Argon2Algo = Argon2Algo; //# sourceMappingURL=Argon2Algo.js.map