Unzureichende Verschlüsselungsstärke

Beschreibung

Unzureichende Verschlüsselungsstärke tritt auf, wenn Software einen kryptografischen Algorithmus oder eine Schlüssellänge verwendet, die unzureichend ist, um Daten gemäß aktuellen Sicherheitsstandards zu schützen. Dies umfasst die Verwendung veralteter Algorithmen (DES, MD5, SHA1 für Sicherheit), zu kurzer Schlüssel (512-Bit RSA, 64-Bit symmetrisch) oder anfälliger Verschlüsselungsmodi (ECB-Modus). Selbst wenn Verschlüsselung vorhanden ist, bietet schwache Verschlüsselung ein falsches Sicherheitsgefühl, da sie mit modernen Rechenressourcen gebrochen werden kann.

Risiko

Schwache Verschlüsselung kann von Angreifern mit moderaten Ressourcen gebrochen werden. DES-Schlüssel können in Stunden per Brute-Force geknackt werden. MD5- und SHA1-Kollisionen können praktisch generiert werden. 512-Bit- oder 1024-Bit-RSA-Schlüssel können faktorisiert werden. ECB-Modus offenbart Muster in Daten. Mit zunehmender Rechenleistung wird Verschlüsselung, die einst ausreichend war, anfällig. Nationalstaatliche Akteure und gut finanzierte kriminelle Organisationen können schwache Verschlüsselung brechen, die hochwertige Ziele schützt.

Lösung

Verwenden Sie AES-256 für symmetrische Verschlüsselung. Verwenden Sie mindestens RSA-2048 (RSA-4096 für langfristige Sicherheit) oder ECDSA/EdDSA mit geeigneten Kurven. Verwenden Sie SHA-256 oder SHA-3 für Hashing, Argon2/bcrypt/scrypt für Passwörter. Vermeiden Sie MD5, SHA1, DES, 3DES, RC4 und Blowfish. Verwenden Sie GCM- oder CCM-Modus, niemals ECB. Folgen Sie NIST-Richtlinien und branchenüblichen Best Practices. Überprüfen und aktualisieren Sie kryptografische Implementierungen regelmäßig, wenn sich Standards weiterentwickeln.

Häufige Auswirkungen

AuswirkungDetails
VertraulichkeitUmfang: Datenoffenlegung

Schwache Verschlüsselung kann gebrochen werden, wodurch verschlüsselte Daten Angreifern offengelegt werden.
IntegritätUmfang: Fälschung

Schwaches Hashing ermöglicht Angreifern, Kollisionen zu erstellen und Signaturen zu fälschen.
AuthentifizierungUmfang: Imitation

Schwache Schlüsselgrößen ermöglichen Schlüsselwiederherstellung und ermöglichen Imitation.

Beispielcode + Korrigierter Code

Anfälliger Code

# ANFÄLLIG: DES-Verschlüsselung (56-Bit-Schlüssel)
from Crypto.Cipher import DES

def encrypt_weak(data, key):
    cipher = DES.new(key[:8], DES.MODE_ECB)  # DES mit ECB-Modus!
    return cipher.encrypt(pad(data))

# ANFÄLLIG: MD5 für Passwort-Hashing
import hashlib

def hash_password_weak(password):
    return hashlib.md5(password.encode()).hexdigest()  # MD5!

# ANFÄLLIG: Kurzer RSA-Schlüssel
from Crypto.PublicKey import RSA

def generate_weak_key():
    return RSA.generate(512)  # Viel zu kurz!

# ANFÄLLIG: SHA1 für Signaturen
def sign_data_weak(data, key):
    h = SHA.new(data)  # SHA1 ist veraltet
    signature = pkcs1_15.new(key).sign(h)
    return signature

# ANFÄLLIG: Schwacher PRNG
import random

def generate_token_weak():
    return random.randint(0, 999999)  # Vorhersagbar!
// ANFÄLLIG: DES-Verschlüsselung
public class WeakCrypto {

    public byte[] encryptWeak(byte[] data, byte[] key) throws Exception {
        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");  // DES + ECB!
        SecretKeySpec keySpec = new SecretKeySpec(key, "DES");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        return cipher.doFinal(data);
    }

    // ANFÄLLIG: MD5-Hashing
    public String hashPasswordWeak(String password) throws Exception {
        MessageDigest md = MessageDigest.getInstance("MD5");
        byte[] hash = md.digest(password.getBytes());
        return bytesToHex(hash);
    }

    // ANFÄLLIG: Kurzer RSA-Schlüssel
    public KeyPair generateWeakKeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(1024);  // Zu kurz für moderne Sicherheit
        return keyGen.generateKeyPair();
    }

    // ANFÄLLIG: RC4-Verschlüsselung
    public byte[] encryptRC4(byte[] data, byte[] key) throws Exception {
        Cipher cipher = Cipher.getInstance("RC4");  // RC4 ist gebrochen
        SecretKeySpec keySpec = new SecretKeySpec(key, "RC4");
        cipher.init(Cipher.ENCRYPT_MODE, keySpec);
        return cipher.doFinal(data);
    }
}
// ANFÄLLIG: Schwache Kryptografie in Node.js
const crypto = require('crypto');

// DES-Verschlüsselung
function encryptWeakDES(data, key) {
    const cipher = crypto.createCipheriv('des', key.slice(0, 8), Buffer.alloc(8));
    return cipher.update(data) + cipher.final();
}

// MD5-Hashing
function hashWeakMD5(data) {
    return crypto.createHash('md5').update(data).digest('hex');
}

// Kurze Schlüsselgenerierung
function generateWeakKey() {
    return crypto.randomBytes(8);  // 64-Bit-Schlüssel
}

// RC4
function encryptWeakRC4(data, key) {
    const cipher = crypto.createCipheriv('rc4', key, '');
    return cipher.update(data) + cipher.final();
}

Korrigierter Code

# SICHER: AES-256-GCM-Verschlüsselung
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.backends import default_backend
import os
import argon2

def encrypt_strong(data, key):
    # Zufällige Nonce generieren
    nonce = os.urandom(12)
    aesgcm = AESGCM(key)  # 256-Bit-Schlüssel
    ciphertext = aesgcm.encrypt(nonce, data, None)
    return nonce + ciphertext

def decrypt_strong(encrypted, key):
    nonce = encrypted[:12]
    ciphertext = encrypted[12:]
    aesgcm = AESGCM(key)
    return aesgcm.decrypt(nonce, ciphertext, None)

# SICHER: Argon2 für Passwort-Hashing
def hash_password_strong(password):
    ph = argon2.PasswordHasher(
        time_cost=3,
        memory_cost=65536,
        parallelism=4
    )
    return ph.hash(password)

def verify_password_strong(hash, password):
    ph = argon2.PasswordHasher()
    try:
        ph.verify(hash, password)
        return True
    except:
        return False

# SICHER: Stärker RSA-Schlüssel
from cryptography.hazmat.primitives.asymmetric import rsa

def generate_strong_key():
    return rsa.generate_private_key(
        public_exponent=65537,
        key_size=4096,  # Stärke Schlüsselgröße
        backend=default_backend()
    )

# SICHER: SHA-256 für Signaturen
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding

def sign_data_strong(data, private_key):
    signature = private_key.sign(
        data,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        hashes.SHA256()  # SHA-256
    )
    return signature

# SICHER: Sicherer Zufall
def generate_token_strong():
    return os.urandom(32).hex()  # 256-Bit kryptografisch sicher
// SICHER: AES-256-GCM
public class StrongCrypto {

    private static final int GCM_IV_LENGTH = 12;
    private static final int GCM_TAG_LENGTH = 128;
    private static final int AES_KEY_SIZE = 256;

    public byte[] encryptStrong(byte[] data, SecretKey key) throws Exception {
        byte[] iv = new byte[GCM_IV_LENGTH];
        SecureRandom random = SecureRandom.getInstanceStrong();
        random.nextBytes(iv);

        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        GCMParameterSpec parameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
        cipher.init(Cipher.ENCRYPT_MODE, key, parameterSpec);

        byte[] ciphertext = cipher.doFinal(data);

        // IV voranstellen
        byte[] result = new byte[iv.length + ciphertext.length];
        System.arraycopy(iv, 0, result, 0, iv.length);
        System.arraycopy(ciphertext, 0, result, iv.length, ciphertext.length);

        return result;
    }

    // SICHER: Argon2 für Passwörter
    public String hashPasswordStrong(String password) {
        Argon2PasswordEncoder encoder = new Argon2PasswordEncoder(
            16,     // Salt-Länge
            32,     // Hash-Länge
            1,      // Parallelität
            65536,  // Speicher (64 MB)
            3       // Iterationen
        );
        return encoder.encode(password);
    }

    // SICHER: Starkes RSA
    public KeyPair generateStrongKeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(4096, SecureRandom.getInstanceStrong());
        return keyGen.generateKeyPair();
    }

    // SICHER: ECDSA mit P-256
    public KeyPair generateECKeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
        ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1");
        keyGen.initialize(ecSpec, SecureRandom.getInstanceStrong());
        return keyGen.generateKeyPair();
    }

    // SICHER: Starken AES-Schlüssel generieren
    public SecretKey generateAESKey() throws Exception {
        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(AES_KEY_SIZE, SecureRandom.getInstanceStrong());
        return keyGen.generateKey();
    }
}
// SICHER: Starke Kryptografie in Node.js
const crypto = require('crypto');
const argon2 = require('argon2');

// AES-256-GCM
function encryptStrong(data, key) {
    const iv = crypto.randomBytes(12);  // 96-Bit IV für GCM
    const cipher = crypto.createCipheriv('aes-256-gcm', key, iv);

    let encrypted = cipher.update(data);
    encrypted = Buffer.concat([encrypted, cipher.final()]);

    const authTag = cipher.getAuthTag();

    // IV + authTag + Geheimtext zurückgeben
    return Buffer.concat([iv, authTag, encrypted]);
}

function decryptStrong(encrypted, key) {
    const iv = encrypted.slice(0, 12);
    const authTag = encrypted.slice(12, 28);
    const ciphertext = encrypted.slice(28);

    const decipher = crypto.createDecipheriv('aes-256-gcm', key, iv);
    decipher.setAuthTag(authTag);

    let decrypted = decipher.update(ciphertext);
    decrypted = Buffer.concat([decrypted, decipher.final()]);

    return decrypted;
}

// Argon2 für Passwörter
async function hashPasswordStrong(password) {
    return await argon2.hash(password, {
        type: argon2.argon2id,
        memoryCost: 65536,
        timeCost: 3,
        parallelism: 4
    });
}

async function verifyPasswordStrong(hash, password) {
    return await argon2.verify(hash, password);
}

// Starke Schlüsselgenerierung
function generateStrongKey() {
    return crypto.randomBytes(32);  // 256-Bit-Schlüssel
}

// SHA-256
function hashStrong(data) {
    return crypto.createHash('sha256').update(data).digest('hex');
}

Ausgenutzt in der Praxis

DROWN-Angriff (2016)

Der DROWN-Angriff nutzte Server aus, die noch SSLv2 mit schwacher Export-Grade-Kryptografie unterstützten, was die Entschlüsselung von TLS-Verbindungen ermöglichte. 33% aller HTTPS-Server waren anfällig.

FREAK-Angriff (2015)

FREAK nutzte schwache Export-Grade-RSA-Schlüssel (512-Bit) aus, um TLS-Verbindungen zu brechen. Clients könnten durch Man-in-the-Middle-Angriffe zur Verwendung schwacher Kryptografie gezwungen werden.

SHA1-Kollision (2017)

Google demonstrierte den ersten praktischen SHA1-Kollisionsangriff und erstellte zwei verschiedene PDFs mit demselben SHA1-Hash, was SHA1 für Sicherheitszwecke effektiv brach.


Tools zum Testen/Ausnutzen

  • testssl.sh — Umfassende TLS/SSL-Tests.

  • Hashcat — Passwort-Hash-Cracking zum Testen der Stärke.

  • OpenSSL — Analyse kryptografischer Konfigurationen.

  • Nmap — Mit ssl-enum-ciphers-Skript.


CVE-Beispiele


Referenzen

  1. MITRE. "CWE-326: Inadequate Encryption Strength." https://cwe.mitre.org/data/definitions/326.html

  2. NIST. "Transitioning the Use of Cryptographic Algorithms and Key Lengths." https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final