**What Changed:**

- **Removed:** All libsodium dependencies and PAKE-based authentication
- **Replaced With:** ECDH + DTLS + SAS triple-layer security system
- **Impact:** Eliminates complex PAKE implementation in favor of standardized protocols

**Security Benefits:**
-  **Simplified Architecture** - Reduced attack surface
-  **Standards Compliance** - RFC-compliant protocols
-  **Better Maintenance** - Native Web Crypto API usage
-  **Enhanced Security** - Triple-layer defense system

**New Features:**
- **Elliptic Curve Diffie-Hellman** using P-384 (secp384r1)
- **Cryptographically secure** key pair generation
- **Perfect Forward Secrecy** with session-specific keys
- **MITM resistance** requiring knowledge of both private keys
This commit is contained in:
lockbitchat
2025-09-04 17:25:01 -04:00
parent 0d029f5d39
commit e2316f6557
11 changed files with 1269 additions and 300 deletions

View File

@@ -71,11 +71,44 @@ class EnhancedSecureCryptoUtils {
}
return bytes.buffer;
} catch (error) {
EnhancedSecureCryptoUtils.secureLog.log('error', 'Base64 to ArrayBuffer conversion failed', { error: error.message });
console.error('Base64 to ArrayBuffer conversion failed:', error.message);
throw new Error(`Base64 conversion error: ${error.message}`);
}
}
// Helper function to convert hex string to Uint8Array
static hexToUint8Array(hexString) {
try {
if (!hexString || typeof hexString !== 'string') {
throw new Error('Invalid hex string input: must be a non-empty string');
}
// Remove colons and spaces from hex string (e.g., "aa:bb:cc" -> "aabbcc")
const cleanHex = hexString.replace(/:/g, '').replace(/\s/g, '');
// Validate hex format
if (!/^[0-9a-fA-F]*$/.test(cleanHex)) {
throw new Error('Invalid hex format: contains non-hex characters');
}
// Ensure even length
if (cleanHex.length % 2 !== 0) {
throw new Error('Invalid hex format: odd length');
}
// Convert hex string to bytes
const bytes = new Uint8Array(cleanHex.length / 2);
for (let i = 0; i < cleanHex.length; i += 2) {
bytes[i / 2] = parseInt(cleanHex.substr(i, 2), 16);
}
return bytes;
} catch (error) {
console.error('Hex to Uint8Array conversion failed:', error.message);
throw new Error(`Hex conversion error: ${error.message}`);
}
}
static async encryptData(data, password) {
try {
const dataString = typeof data === 'string' ? data : JSON.stringify(data);
@@ -124,7 +157,7 @@ class EnhancedSecureCryptoUtils {
return EnhancedSecureCryptoUtils.arrayBufferToBase64(new TextEncoder().encode(packageString).buffer);
} catch (error) {
EnhancedSecureCryptoUtils.secureLog.log('error', 'Encryption failed', { error: error.message });
console.error('Encryption failed:', error.message);
throw new Error(`Encryption error: ${error.message}`);
}
}
@@ -182,7 +215,7 @@ class EnhancedSecureCryptoUtils {
}
} catch (error) {
EnhancedSecureCryptoUtils.secureLog.log('error', 'Decryption failed', { error: error.message });
console.error('Decryption failed:', error.message);
throw new Error(`Decryption error: ${error.message}`);
}
}
@@ -211,7 +244,7 @@ class EnhancedSecureCryptoUtils {
try {
// Fallback to basic calculation if securityManager is not fully initialized
if (!securityManager || !securityManager.securityFeatures) {
EnhancedSecureCryptoUtils.secureLog.log('warn', 'Security manager not fully initialized, using fallback calculation');
console.warn('Security manager not fully initialized, using fallback calculation');
return {
level: 'INITIALIZING',
score: 0,
@@ -342,7 +375,7 @@ class EnhancedSecureCryptoUtils {
maxPossibleScore: isDemoSession ? 50 : 100 // Demo sessions can only get max 50 points (4 checks)
};
EnhancedSecureCryptoUtils.secureLog.log('info', 'Real security level calculated', {
console.log('Real security level calculated:', {
score: percentage,
level: result.level,
passedChecks: passedChecks,
@@ -353,7 +386,7 @@ class EnhancedSecureCryptoUtils {
return result;
} catch (error) {
EnhancedSecureCryptoUtils.secureLog.log('error', 'Security level calculation failed', { error: error.message });
console.error('Security level calculation failed:', error.message);
return {
level: 'UNKNOWN',
score: 0,
@@ -392,7 +425,7 @@ class EnhancedSecureCryptoUtils {
const decryptedText = new TextDecoder().decode(decrypted);
return decryptedText === testData;
} catch (error) {
EnhancedSecureCryptoUtils.secureLog.log('error', 'Encryption verification failed', { error: error.message });
console.error('Encryption verification failed:', error.message);
return false;
}
}
@@ -409,7 +442,7 @@ class EnhancedSecureCryptoUtils {
return keyType === 'ECDH' && (curve === 'P-384' || curve === 'P-256');
} catch (error) {
EnhancedSecureCryptoUtils.secureLog.log('error', 'ECDH verification failed', { error: error.message });
console.error('ECDH verification failed:', error.message);
return false;
}
}
@@ -440,14 +473,18 @@ class EnhancedSecureCryptoUtils {
return isValid;
} catch (error) {
EnhancedSecureCryptoUtils.secureLog.log('error', 'ECDSA verification failed', { error: error.message });
console.error('ECDSA verification failed:', error.message);
return false;
}
}
static async verifyMessageIntegrity(securityManager) {
try {
if (!securityManager.macKey) return false;
// Check if macKey exists and is a valid CryptoKey
if (!securityManager.macKey || !(securityManager.macKey instanceof CryptoKey)) {
console.warn('MAC key not available or invalid for message integrity verification');
return false;
}
// Test message integrity with HMAC
const testData = 'Test message integrity verification';
@@ -469,14 +506,18 @@ class EnhancedSecureCryptoUtils {
return isValid;
} catch (error) {
EnhancedSecureCryptoUtils.secureLog.log('error', 'Message integrity verification failed', { error: error.message });
console.error('Message integrity verification failed:', error.message);
return false;
}
}
static async verifyNestedEncryption(securityManager) {
try {
if (!securityManager.nestedEncryptionKey) return false;
// Check if nestedEncryptionKey exists and is a valid CryptoKey
if (!securityManager.nestedEncryptionKey || !(securityManager.nestedEncryptionKey instanceof CryptoKey)) {
console.warn('Nested encryption key not available or invalid');
return false;
}
// Test nested encryption
const testData = 'Test nested encryption verification';
@@ -492,7 +533,7 @@ class EnhancedSecureCryptoUtils {
return encrypted && encrypted.byteLength > 0;
} catch (error) {
EnhancedSecureCryptoUtils.secureLog.log('error', 'Nested encryption verification failed', { error: error.message });
console.error('Nested encryption verification failed:', error.message);
return false;
}
}
@@ -814,10 +855,10 @@ class EnhancedSecureCryptoUtils {
if (this.isProductionMode) {
if (level === 'error') {
// В production показываем только код ошибки без деталей
this._secureLog('error', '❌ [SecureChat] ${message} [ERROR_CODE: ${this._generateErrorCode(message)}]');
console.error(`❌ [SecureChat] ${message} [ERROR_CODE: ${this._generateErrorCode(message)}]`);
} else if (level === 'warn') {
// В production показываем только предупреждение без контекста
this._secureLog('warn', '⚠️ [SecureChat] ${message}');
console.warn(`⚠️ [SecureChat] ${message}`);
} else {
// В production не показываем info/debug логи
return;
@@ -825,9 +866,9 @@ class EnhancedSecureCryptoUtils {
} else {
// Development mode - показываем все
if (level === 'error') {
this._secureLog('error', '❌ [SecureChat] ${message}', { errorType: sanitizedContext?.constructor?.name || 'Unknown' });
console.error(`❌ [SecureChat] ${message}`, { errorType: sanitizedContext?.constructor?.name || 'Unknown' });
} else if (level === 'warn') {
this._secureLog('warn', '⚠️ [SecureChat] ${message}', { details: sanitizedContext });
console.warn(`⚠️ [SecureChat] ${message}`, { details: sanitizedContext });
} else {
console.log(`[SecureChat] ${message}`, sanitizedContext);
}