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
JavaScript
;
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