@@ -903,12 +903,15 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils {
903903 // Generate secure password for data exchange
904904 static generateSecurePassword() {
905905 const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()_+-=[]{}|;:,.<>?";
906+ const charCount = chars.length;
906907 const length = 32;
907- const randomValues = new Uint32Array(length);
908- crypto.getRandomValues(randomValues);
909908 let password = "";
910909 for (let i = 0; i < length; i++) {
911- password += chars[randomValues[i] % chars.length];
910+ let randomValue;
911+ do {
912+ randomValue = crypto.getRandomValues(new Uint32Array(1))[0];
913+ } while (randomValue >= 4294967296 - 4294967296 % charCount);
914+ password += chars[randomValue % charCount];
912915 }
913916 return password;
914917 }
@@ -2591,10 +2594,14 @@ var EnhancedSecureCryptoUtils = class _EnhancedSecureCryptoUtils {
25912594 // Generate verification code for out-of-band authentication
25922595 static generateVerificationCode() {
25932596 const chars = "0123456789ABCDEF";
2597+ const charCount = chars.length;
25942598 let result = "";
2595- const values = crypto.getRandomValues(new Uint8Array(6));
25962599 for (let i = 0; i < 6; i++) {
2597- result += chars[values[i] % chars.length];
2600+ let randomByte;
2601+ do {
2602+ randomByte = crypto.getRandomValues(new Uint8Array(1))[0];
2603+ } while (randomByte >= 256 - 256 % charCount);
2604+ result += chars[randomByte % charCount];
25982605 }
25992606 return result.match(/.{1,2}/g).join("-");
26002607 }
@@ -4875,12 +4882,13 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
48754882 preserveMessageSize: this._config.packetPadding.preserveMessageSize
48764883 };
48774884 this.fakeTrafficConfig = {
4878- enabled: this._config.fakeTraffic.enabled,
4879- minInterval: this._config.fakeTraffic.minInterval,
4880- maxInterval: this._config.fakeTraffic.maxInterval,
4881- minSize: this._config.fakeTraffic.minSize,
4882- maxSize: this._config.fakeTraffic.maxSize,
4883- patterns: this._config.fakeTraffic.patterns
4885+ enabled: this._config.fakeTraffic?.enabled || false,
4886+ minInterval: this._config.fakeTraffic?.minInterval || 15e3,
4887+ maxInterval: this._config.fakeTraffic?.maxInterval || 3e4,
4888+ minSize: this._config.fakeTraffic?.minSize || 64,
4889+ maxSize: this._config.fakeTraffic?.maxSize || 1024,
4890+ patterns: this._config.fakeTraffic?.patterns || ["heartbeat", "status", "ping"],
4891+ randomDecoyIntervals: this._config.fakeTraffic?.randomDecoyIntervals || true
48844892 };
48854893 this.fakeTrafficTimer = null;
48864894 this.lastFakeTraffic = 0;
@@ -7447,7 +7455,11 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
74477455 );
74487456 const dv = new DataView(bits);
74497457 const n = (dv.getUint32(0) ^ dv.getUint32(4)) >>> 0;
7450- const sasCode = String(n % 1e7).padStart(7, "0");
7458+ let sasValue;
7459+ do {
7460+ sasValue = crypto.getRandomValues(new Uint32Array(1))[0];
7461+ } while (sasValue >= 4294967296 - 4294967296 % 1e7);
7462+ const sasCode = String(sasValue % 1e7).padStart(7, "0");
74517463 this._secureLog("info", "SAS code computed successfully", {
74527464 localFP: localFP.substring(0, 16) + "...",
74537465 remoteFP: remoteFP.substring(0, 16) + "...",
@@ -8121,13 +8133,36 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
81218133 this._secureLog("error", "\u274C Failed to initialize enhanced security", { errorType: error.constructor.name });
81228134 }
81238135 }
8136+ // Helper function to generate unbiased random values in a range
8137+ getUnbiasedRandomInRange(min, max) {
8138+ const range = max - min + 1;
8139+ if (range > 256) {
8140+ const bytesNeeded = Math.ceil(Math.log2(range) / 8);
8141+ const maxValue = Math.pow(256, bytesNeeded);
8142+ const threshold = maxValue - maxValue % range;
8143+ let randomValue2;
8144+ do {
8145+ const randomBytes = crypto.getRandomValues(new Uint8Array(bytesNeeded));
8146+ randomValue2 = 0;
8147+ for (let i = 0; i < bytesNeeded; i++) {
8148+ randomValue2 = (randomValue2 << 8) + randomBytes[i];
8149+ }
8150+ } while (randomValue2 >= threshold);
8151+ return randomValue2 % range + min;
8152+ }
8153+ let randomValue;
8154+ do {
8155+ randomValue = crypto.getRandomValues(new Uint8Array(1))[0];
8156+ } while (randomValue >= 256 - 256 % range);
8157+ return randomValue % range + min;
8158+ }
81248159 // Generate fingerprint mask for anti-fingerprinting with enhanced randomization
81258160 generateFingerprintMask() {
81268161 const cryptoRandom = crypto.getRandomValues(new Uint8Array(128));
81278162 const mask = {
8128- timingOffset: cryptoRandom[0] % 1e3 + cryptoRandom[1] % 500 ,
8163+ timingOffset: this.getUnbiasedRandomInRange(0, 1500) ,
81298164 // 0-1500ms
8130- sizeVariation: (cryptoRandom[2] % 50 + 75 ) / 100,
8165+ sizeVariation: this.getUnbiasedRandomInRange(75, 125 ) / 100,
81318166 // 0.75 to 1.25
81328167 noisePattern: Array.from(crypto.getRandomValues(new Uint8Array(64))),
81338168 // Increased size
@@ -8144,11 +8179,11 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
81448179 "X-Anonymous",
81458180 "X-Private"
81468181 ],
8147- noiseIntensity: cryptoRandom[3] % 100 + 50 ,
8182+ noiseIntensity: this.getUnbiasedRandomInRange(50, 150) ,
81488183 // 50-150%
8149- sizeMultiplier: (cryptoRandom[4] % 50 + 75 ) / 100,
8184+ sizeMultiplier: this.getUnbiasedRandomInRange(75, 125 ) / 100,
81508185 // 0.75-1.25
8151- timingVariation: cryptoRandom[5] % 1e3 + 100
8186+ timingVariation: this.getUnbiasedRandomInRange( 100, 1100)
81528187 // 100-1100ms
81538188 };
81548189 return mask;
@@ -8478,7 +8513,10 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
84788513 try {
84798514 const fakeMessage = this.generateFakeMessage();
84808515 await this.sendFakeMessage(fakeMessage);
8481- const nextInterval = this.fakeTrafficConfig.randomDecoyIntervals ? Math.random() * (this.fakeTrafficConfig.maxInterval - this.fakeTrafficConfig.minInterval) + this.fakeTrafficConfig.minInterval : this.fakeTrafficConfig.minInterval;
8516+ const nextInterval = this.fakeTrafficConfig.randomDecoyIntervals ? this.getUnbiasedRandomInRange(this.fakeTrafficConfig.minInterval, Math.min(this.fakeTrafficConfig.maxInterval, 6e4)) : (
8517+ // Cap at 60 seconds
8518+ this.fakeTrafficConfig.minInterval
8519+ );
84828520 const safeInterval = Math.max(nextInterval, _EnhancedSecureWebRTCManager.TIMEOUTS.FAKE_TRAFFIC_MIN_INTERVAL);
84838521 this.fakeTrafficTimer = setTimeout(sendFakeMessage, safeInterval);
84848522 } catch (error) {
@@ -8488,7 +8526,9 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
84888526 this.stopFakeTrafficGeneration();
84898527 }
84908528 };
8491- const initialDelay = Math.random() * this.fakeTrafficConfig.maxInterval + _EnhancedSecureWebRTCManager.TIMEOUTS.DECOY_INITIAL_DELAY;
8529+ const minDelay = _EnhancedSecureWebRTCManager.TIMEOUTS.DECOY_INITIAL_DELAY;
8530+ const maxDelay = Math.min(this.fakeTrafficConfig.maxInterval, 3e4);
8531+ const initialDelay = this.getUnbiasedRandomInRange(minDelay, maxDelay);
84928532 this.fakeTrafficTimer = setTimeout(sendFakeMessage, initialDelay);
84938533 }
84948534 stopFakeTrafficGeneration() {
@@ -8498,8 +8538,9 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
84988538 }
84998539 }
85008540 generateFakeMessage() {
8501- const pattern = this.fakeTrafficConfig.patterns[Math.floor(Math.random() * this.fakeTrafficConfig.patterns.length)];
8502- const size = Math.floor(Math.random() * (this.fakeTrafficConfig.maxSize - this.fakeTrafficConfig.minSize + 1)) + this.fakeTrafficConfig.minSize;
8541+ const patternIndex = this.getUnbiasedRandomInRange(0, this.fakeTrafficConfig.patterns.length - 1);
8542+ const pattern = this.fakeTrafficConfig.patterns[patternIndex];
8543+ const size = this.getUnbiasedRandomInRange(this.fakeTrafficConfig.minSize, this.fakeTrafficConfig.maxSize);
85038544 const fakeData = crypto.getRandomValues(new Uint8Array(size));
85048545 return {
85058546 type: _EnhancedSecureWebRTCManager.MESSAGE_TYPES.FAKE,
@@ -8961,7 +9002,7 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
89619002 }
89629003 addNoise(data) {
89639004 const dataArray = new Uint8Array(data);
8964- const noiseSize = Math.floor(Math.random() * 32) + 8 ;
9005+ const noiseSize = this.getUnbiasedRandomInRange(8, 40) ;
89659006 const noise = crypto.getRandomValues(new Uint8Array(noiseSize));
89669007 const result = new Uint8Array(dataArray.length + noiseSize);
89679008 result.set(dataArray, 0);
@@ -8994,16 +9035,24 @@ var EnhancedSecureWebRTCManager = class _EnhancedSecureWebRTCManager {
89949035 }
89959036 addRandomHeaders(data) {
89969037 const dataArray = new Uint8Array(data);
8997- const headerCount = Math.floor(Math.random() * 3) + 1 ;
9038+ const headerCount = this.getUnbiasedRandomInRange(1, 3) ;
89989039 let totalHeaderSize = 0;
89999040 for (let i = 0; i < headerCount; i++) {
9000- totalHeaderSize += 4 + Math.floor(Math.random() * 16 ) + 4;
9041+ totalHeaderSize += 4 + this.getUnbiasedRandomInRange(0, 15 ) + 4;
90019042 }
90029043 const result = new Uint8Array(totalHeaderSize + dataArray.length);
90039044 let offset = 0;
90049045 for (let i = 0; i < headerCount; i++) {
9005- const headerName = this.fingerprintMask.headerVariations[Math.floor(Math.random() * this.fingerprintMask.headerVariations.length)];
9006- const headerData = crypto.getRandomValues(new Uint8Array(Math.floor(Math.random() * 16) + 4));
9046+ let headerIndex;
9047+ do {
9048+ headerIndex = crypto.getRandomValues(new Uint8Array(1))[0];
9049+ } while (headerIndex >= 256 - 256 % this.fingerprintMask.headerVariations.length);
9050+ const headerName = this.fingerprintMask.headerVariations[headerIndex % this.fingerprintMask.headerVariations.length];
9051+ let headerSize;
9052+ do {
9053+ headerSize = crypto.getRandomValues(new Uint8Array(1))[0];
9054+ } while (headerSize >= 256 - 256 % 16);
9055+ const headerData = crypto.getRandomValues(new Uint8Array(headerSize % 16 + 4));
90079056 const headerView = new DataView(result.buffer, offset);
90089057 headerView.setUint32(0, headerData.length + 8, false);
90099058 headerView.setUint32(4, this.hashString(headerName), false);
0 commit comments