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
| Auswirkung | Details |
|---|---|
| Vertraulichkeit | Umfang: Datenoffenlegung Schwache Verschlüsselung kann gebrochen werden, wodurch verschlüsselte Daten Angreifern offengelegt werden. |
| Integrität | Umfang: Fälschung Schwaches Hashing ermöglicht Angreifern, Kollisionen zu erstellen und Signaturen zu fälschen. |
| Authentifizierung | Umfang: 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
-
CVE-2016-0800 — DROWN-Angriff auf SSLv2.
-
CVE-2015-0204 — FREAK-Angriff schwache RSA-Schlüssel.
-
CVE-2020-1968 — OpenSSL schwaches Diffie-Hellman.
Referenzen
-
MITRE. "CWE-326: Inadequate Encryption Strength." https://cwe.mitre.org/data/definitions/326.html
-
NIST. "Transitioning the Use of Cryptographic Algorithms and Key Lengths." https://csrc.nist.gov/publications/detail/sp/800-131a/rev-2/final