Sichere USB-Verschlüsselung in Python: Speichermanagement und Stream-Verarbeitung
Für sichere Dateiübertragungen per USB gilt: Einfachheit ist entscheidend. Stecken Sie das Laufwerk ein, geben Sie ein Passwort ein und greifen auf verschlüsselte Daten zu. VeraCrypt nutzt Container-Dateien, was die direkte Verwendung über verschiedene Betriebssysteme erschwert. Die Hauptaufgabe? Der Schutz vor Datenkorruption bei plötzlichem Stromausfall, wenn ein Flash-Laufwerk während der Verschlüsselung herausgezogen wird.
Ein Krypto-Engine in Python nutzt AES-GCM und ChaCha20. Der Fokus liegt auf sicherer Speicherung von Schlüsseln im RAM, der Streaming-Verschlüsselung von Gigabyte-Dateien ohne Auslastung des Arbeitsspeichers und robusten Integritätsmechanismen.
Die SecureBytes-Klasse beseitigt eine kritische Schwachstelle in Python und Java: Die Garbage Collection (GC), die sensible Daten (Passwörter, Schlüssel) in neue Speicherbereiche kopiert und dadurch Spuren im RAM hinterlässt. So funktioniert es:
class SecureBytes:
def __init__(self, data: Union[bytes, bytearray, int]):
if isinstance(data, int):
self._buffer = bytearray(data)
else:
self._buffer = bytearray(data)
self._finalized = False
# Schwachen Finalizer registrieren
self._weak_ref = weakref.ref(self, self._cleanup_callback)
def wipe(self, passes: int = 3):
if self._finalized or len(self._buffer) == 0:
return
# Durchgang 1: Zufallsbytes
self._buffer[:] = secrets.token_bytes(len(self._buffer))
# Durchgang 2: Nullen
self._buffer[:] = b'\x00' * len(self._buffer)
self._finalized = True
gc.collect()
def __del__(self):
if not self._finalized:
self.wipe()
Wichtige Funktionen:
- Nutzung von
bytearrayfür In-Place-Überschreibungen – im Gegensatz zu unveränderlichenbytes. - Mehrfach-Wiping: Zuerst zufällige Daten, dann Nullen (gemäß NIST SP 800-88).
- Entwickelt für den Einsatz mit Kontext-Managern (
with secure_key(...)) zur sicheren Bereinigung auch bei Ausnahmen.
Dies minimiert die Exposition von Schlüsseln im Speicher und verhindert Lecks durch GC.
Streaming-Verschlüsselung: MemorySensitiveReader
Die Verschlüsselung einer 10-GB-Datei auf einem Gerät mit nur 4 GB RAM erfordert einen Streaming-Ansatz. Die MemorySensitiveReader-Klasse wechselt automatisch zwischen Modus je nach Dateigröße und verfügbarem Speicher:
class MemorySensitiveReader:
def __init__(self, file_path: str, memory_threshold: int = 100 * 1024 * 1024):
self.file_size = os.path.getsize(file_path)
# Schwellenwert zum Wechsel in Streaming-Modus
self.use_streaming = self.file_size > memory_threshold
def iter_chunks(self, chunk_size: int = 8192):
# Lesen und Verschlüsseln in Blöcken
...
Lösung des Nonce-Problems: Die Wiederverwendung desselben Nonce mit einem einzigen Schlüssel in AES-GCM oder ChaCha20 ist katastrophal. Um dies zu verhindern, erhält jeder Block einen eindeutigen Nonce, abgeleitet aus einem Basis-Nonce und dem Blockindex:
def _derive_block_nonce_12bit(base_nonce: bytes, block_index: int) -> bytes:
# Erste 8 Bytes = Präfix, letzte 4 = Block-Zähler
prefix = base_nonce[:8]
block_counter = block_index.to_bytes(4, byteorder='big')
return prefix + block_counter
Blöcke werden in 8 KB-Chunks gelesen, Nonces aus Basiswert und Index generiert – garantiert kryptografische Stärke unabhängig von der Dateigröße.
Fehlerresistenz bei Operationen
Standard-Verschlüsselung, die die Originaldatei bei Fehlern löscht, führt zu dauerhafter Datenverlust. Dieses System beinhaltet:
- Sperrdatei
.encryption_lock.json: Verfolgt den Status alsin_progressund listet verarbeitete Dateien auf. - Temporäre
.tmp-Dateien: Verschlüsselt in eine Kopie; Original wird erst nach erfolgreicher Überprüfung gelöscht. - Integritätsprüfungen: Dekodieren eines Blocks, Vergleich von HMAC und SHA-256-Hashes.
- Rollback-Mechanismus: Bei Unterbrechung wird automatisch das Original aus der verschlüsselten Datei wiederhergestellt.
Damit ist sichergestellt, dass nach einem Stromausfall die Daten entweder vollständig verschlüsselt sind oder völlig unberührt – keine halbverschlüsselten Zustände.
Unterstützte Algorithmen
- AES-256-GCM: Nutzt Hardware-Beschleunigung via AES-NI.
- ChaCha20-Poly1305: Optimaler Leistungsaufwand auf ARM-Geräten ohne AES-NI.
- XChaCha20-Poly1305: 24-Byte-Nonce für großflächige Verschlüsselung.
Parallelisierung mittels ThreadPoolExecutor steigert die I/O-Leistung bei vielen kleinen Dateien und umgeht die GIL-Beschränkung.
Was zählt:
SecureBytesverhindert Schlüssel-Lecks durch GC mittels Mehrfach-Wiping.- Streaming-Verschlüsselung mit eindeutigen Nonces für Dateien ab 100 MB – keinerlei Kollisionsrisiko.
- Vollständige Fehlerresistenz: Sperrdateien und automatischer Rollback bei Stromausfall.
- Unterstützung für AES-GCM, ChaCha20, XChaCha20 – ohne Sicherheitsverlust.
- Metadaten gespeichert in
.usb_crypt_meta.json, Passwörter ≥12 Zeichen mit Validierung.
Einschränkungen & Bedrohungsmodell
Das Tool schützt vor verlorenen oder gestohlenen Laufwerken, verbirgt aber keine Dateinamen oder Verzeichnisstruktur. Es bietet keinen Schutz gegen Keylogger auf dem Host-System. Ideal für mittlere bis erfahrene Entwickler, die eine benutzerdefinierte USB-Verschlüsselung mit starkem Fokus auf Speichersicherheit und Robustheit benötigen.
— Editorial Team
Noch keine Kommentare.