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