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.

427 lines (421 loc) 14.5 kB
'use strict'; var crypto = require('crypto'); function _interopNamespaceDefault(e) { var n = Object.create(null); if (e) { Object.keys(e).forEach(function (k) { if (k !== 'default') { var d = Object.getOwnPropertyDescriptor(e, k); Object.defineProperty(n, k, d.get ? d : { enumerable: true, get: function () { return e[k]; } }); } }); } n.default = e; return Object.freeze(n); } var crypto__namespace = /*#__PURE__*/_interopNamespaceDefault(crypto); /** * Random sources - Multiple entropy sources and library management */ // ============================================================================ // LIBRARY INSTANCES // ============================================================================ // Safe library instances with proper typing let sodium = null; let forge = null; let secureRandomBytes = null; let randombytes = null; let nobleHashes = null; let tweetnacl = null; // Additional libraries for enhanced security let kyber = null; let entropyString = null; let cryptoJs = null; let elliptic = null; let nobleCurves = null; // Library availability flags const libraryStatus = { sodium: false, forge: false, secureRandom: false, randombytes: false, nobleHashes: false, tweetnacl: false, kyber: false, entropyString: false, cryptoJs: false, elliptic: false, nobleCurves: false, }; // ============================================================================ // LIBRARY INITIALIZATION // ============================================================================ class RandomSources { /** * Initialize all security libraries with comprehensive error handling */ static async initializeLibraries() { if (RandomSources.initialized) { return; } if (RandomSources.initializationPromise) { return RandomSources.initializationPromise; } RandomSources.initializationPromise = RandomSources.performInitialization(); await RandomSources.initializationPromise; RandomSources.initialized = true; } static async performInitialization() { // Initialize libsodium with proper async handling await RandomSources.initializeSodium(); // Initialize other libraries RandomSources.initializeForge(); RandomSources.initializeSecureRandom(); RandomSources.initializeRandomBytes(); RandomSources.initializeNobleHashes(); RandomSources.initializeTweetNaCl(); RandomSources.initializeAdditionalLibraries(); } static async initializeSodium() { try { const sodiumLib = require("libsodium-wrappers"); if (sodiumLib) { // Wait for sodium to be ready if it has a ready promise if (sodiumLib.ready && typeof sodiumLib.ready.then === "function") { await sodiumLib.ready; } // Verify required methods exist if (typeof sodiumLib.randombytes_buf === "function") { sodium = sodiumLib; libraryStatus.sodium = true; } else { console.warn("⚠️ libsodium-wrappers loaded but randombytes_buf method not available"); } } } catch (e) { console.warn("⚠️ libsodium-wrappers not available:", e.message); } } static initializeForge() { try { const forgeLib = require("node-forge"); if (forgeLib && forgeLib.random && typeof forgeLib.random.getBytesSync === "function") { forge = forgeLib; libraryStatus.forge = true; } } catch (e) { console.warn("⚠️ node-forge not available:", e.message); } } static initializeSecureRandom() { try { const secureRandomLib = require("secure-random"); if (secureRandomLib) { if (typeof secureRandomLib === "function" || typeof secureRandomLib.randomBytes === "function") { secureRandomBytes = secureRandomLib; libraryStatus.secureRandom = true; } } } catch (e) { console.warn("⚠️ secure-random not available:", e.message); } } static initializeRandomBytes() { try { const randombytesLib = require("randombytes"); if (randombytesLib && typeof randombytesLib === "function") { randombytes = randombytesLib; libraryStatus.randombytes = true; } } catch (e) { console.warn("⚠️ randombytes not available:", e.message); } } static initializeNobleHashes() { try { // Import specific submodules instead of root module const sha256Lib = require("@noble/hashes/sha256"); const sha512Lib = require("@noble/hashes/sha512"); if (sha256Lib && sha256Lib.sha256 && sha512Lib && sha512Lib.sha512) { nobleHashes = { sha256: sha256Lib.sha256, sha512: sha512Lib.sha512, }; libraryStatus.nobleHashes = true; } } catch (e) { console.warn("⚠️ @noble/hashes not available:", e.message); } } static initializeTweetNaCl() { try { const tweetnaclLib = require("tweetnacl"); if (tweetnaclLib && typeof tweetnaclLib.randomBytes === "function") { tweetnacl = tweetnaclLib; libraryStatus.tweetnacl = true; } } catch (e) { console.warn("⚠️ tweetnacl not available:", e.message); } } static initializeAdditionalLibraries() { // Initialize crystals-kyber try { kyber = require("crystals-kyber"); libraryStatus.kyber = true; } catch (e) { console.warn("⚠️ crystals-kyber not available, using fallback"); } // Initialize entropy-string try { entropyString = require("entropy-string"); libraryStatus.entropyString = true; } catch (e) { console.warn("⚠️ entropy-string not available"); } // Initialize crypto-js try { cryptoJs = require("crypto-js"); libraryStatus.cryptoJs = true; } catch (e) { console.warn("⚠️ crypto-js not available"); } // Initialize elliptic try { elliptic = require("elliptic"); libraryStatus.elliptic = true; } catch (e) { console.warn("⚠️ elliptic not available"); } // Initialize @noble/curves - import specific submodules try { // Import specific curve implementations instead of root module const secp256k1Lib = require("@noble/curves/secp256k1"); const ed25519Lib = require("@noble/curves/ed25519"); if (secp256k1Lib && ed25519Lib) { nobleCurves = { secp256k1: secp256k1Lib, ed25519: ed25519Lib, }; libraryStatus.nobleCurves = true; } } catch (e) { console.warn("⚠️ @noble/curves not available"); } } // ============================================================================ // ENTROPY SOURCE MANAGEMENT // ============================================================================ /** * Get system entropy from multiple CSPRNG sources (military-grade) */ static getSystemEntropy(size) { const sources = []; // Primary: Node.js crypto try { sources.push(crypto__namespace.randomBytes(size)); } catch (error) { console.warn("Node.js crypto randomBytes failed"); } // Secondary: libsodium (if available) if (sodium && libraryStatus.sodium) { try { const sodiumBytes = sodium.randombytes_buf(size); sources.push(Buffer.from(sodiumBytes)); } catch (error) { console.warn("libsodium randomBytes failed"); } } // Tertiary: secure-random package (if available) if (secureRandomBytes && libraryStatus.secureRandom) { try { let secureBytes; if (typeof secureRandomBytes === "function") { secureBytes = secureRandomBytes(size); } else if (secureRandomBytes.randomBytes) { secureBytes = secureRandomBytes.randomBytes(size); } else { throw new Error("Invalid secure-random interface"); } sources.push(Buffer.from(secureBytes)); } catch (error) { console.warn("secure-random failed:", error.message); } } // Quaternary: randombytes package (if available) if (randombytes && libraryStatus.randombytes) { try { const randomBytesBuffer = randombytes(size); sources.push(randomBytesBuffer); } catch (error) { console.warn("randombytes failed"); } } // Quinary: tweetnacl (if available) if (tweetnacl && libraryStatus.tweetnacl) { try { const naclBytes = tweetnacl.randomBytes(size); sources.push(Buffer.from(naclBytes)); } catch (error) { console.warn("tweetnacl randomBytes failed"); } } if (sources.length === 0) { // Ultimate fallback return RandomSources.getFallbackEntropy(size); } // Combine all entropy sources using cryptographic mixing return RandomSources.combineEntropySources(sources, size); } /** * Cryptographically combine multiple entropy sources */ static combineEntropySources(sources, targetSize) { if (sources.length === 1) { return sources[0].slice(0, targetSize); } // XOR all sources together let combined = Buffer.alloc(targetSize); for (const source of sources) { for (let i = 0; i < targetSize; i++) { combined[i] ^= source[i % source.length]; } } // Hash the combined result for uniform distribution const hash = crypto__namespace.createHash("sha512").update(combined).digest(); return hash.slice(0, targetSize); } /** * Get fallback entropy when all other sources fail */ static getFallbackEntropy(size) { console.warn("Using fallback entropy - not cryptographically secure!"); const buffer = Buffer.alloc(size); // Use multiple weak sources combined for (let i = 0; i < size; i++) { buffer[i] = Math.floor(Math.random() * 256) ^ (Date.now() & 0xff) ^ (Number(process.hrtime.bigint()) & 0xff); } return buffer; } /** * Get library status */ static getLibraryStatus() { return { ...libraryStatus }; } /** * Get available entropy sources */ static getAvailableEntropySources() { const sources = [ { name: "node-crypto", enabled: true, priority: 1, fallbackAvailable: true, }, { name: "libsodium", enabled: libraryStatus.sodium, priority: 2, fallbackAvailable: false, }, { name: "secure-random", enabled: libraryStatus.secureRandom, priority: 3, fallbackAvailable: false, }, { name: "randombytes", enabled: libraryStatus.randombytes, priority: 4, fallbackAvailable: false, }, { name: "tweetnacl", enabled: libraryStatus.tweetnacl, priority: 5, fallbackAvailable: false, }, ]; return sources.filter((source) => source.enabled); } /** * Test entropy source availability */ static testEntropySource(sourceName) { try { switch (sourceName) { case "node-crypto": crypto__namespace.randomBytes(1); return true; case "libsodium": if (sodium && libraryStatus.sodium) { sodium.randombytes_buf(1); return true; } return false; case "secure-random": if (secureRandomBytes && libraryStatus.secureRandom) { if (typeof secureRandomBytes === "function") { secureRandomBytes(1); } else if (secureRandomBytes.randomBytes) { secureRandomBytes.randomBytes(1); } return true; } return false; default: return false; } } catch (error) { return false; } } } RandomSources.initialized = false; RandomSources.initializationPromise = null; // Initialize libraries immediately RandomSources.initializeLibraries().catch((error) => { console.error("Failed to initialize security libraries:", error); }); exports.RandomSources = RandomSources; //# sourceMappingURL=random-sources.js.map