Zpět na domů

Python crypto pro USB: SecureBytes a streamové šifrování

Článek popisuje crypto-motor pro USB v Pythonu s třídou SecureBytes pro bezpečné ukládání klíčů, streamovým šifrováním velkých souborů a mechanismy odolnosti vůči selháním. Podpora AES-GCM, ChaCha20. Zaměření na odstranění zranitelností paměti a výpadky napájení.

Vytváříme crypto-motor pro flashky: Python bez úniků paměti
Advertisement 728x90

Bezpečné šifrování USB klíčů v Pythonu: správa paměti a proudové zpracování

Pro bezpečný přenos souborů přes USB je potřeba jednoduchost: vložení nosiče, zadání hesla, přístup k zašifrovaným datům. VeraCrypt vytváří kontejnery, což komplikuje práci s jednotlivými soubory na různých operačních systémech. Klíčový problém spočívá v ochraně proti poškození při náhlém vypnutí napájení, kdy je flashdisk vyjmut během šifrování.

Vytvořen je crypto engine v Pythonu s použitím AES-GCM a ChaCha20. Zaměření je na bezpečné uchování klíčů v paměti, proudové šifrování gigabajtových souborů bez přetížení RAM a mechanismy integrity dat.

Bezpečné uchování klíčů: třída SecureBytes

V Pythonu a Java GC kopíruje citlivá data (hesla, klíče) do nových míst paměti, zanechávajíce kopie v RAM. Třída SecureBytes odstraňuje tuto zranitelnost:

Google AdInline article slot
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
        # Registrován slabý finalizátor
        self._weak_ref = weakref.ref(self, self._cleanup_callback)

    def wipe(self, passes: int = 3):
        if self._finalized or len(self._buffer) == 0:
            return
        # První průchod: náhodná data
        self._buffer[:] = secrets.token_bytes(len(self._buffer))
        # Druhý průchod: nuly
        self._buffer[:] = b'\x00' * len(self._buffer)
        self._finalized = True
        gc.collect()

    def __del__(self):
        if not self._finalized:
            self.wipe()

Klíčové vlastnosti:

  • bytearray pro přepsání na místě, na rozdíl od neměnných bytes.
  • Víceprůchodná čistka: náhodné bajty, pak nuly (NIST SP 800-88).
  • Použití v kontextovém manažeru with secure_key(...) pro zaručenou čistku při výjimkách.

Tím se minimalizuje doba přítomnosti klíčů v paměti a zabrání se únikům prostřednictvím GC.

Proudové šifrování: MemorySensitiveReader

Šifrování 10 GB souboru na stroji s 4 GB RAM vyžaduje proudový přístup. Třída MemorySensitiveReader vybírá režim podle velikosti souboru a dostupné paměti:

Google AdInline article slot
class MemorySensitiveReader:
    def __init__(self, file_path: str, memory_threshold: int = 100 * 1024 * 1024):
        self.file_size = os.path.getsize(file_path)
        # Práh přepnutí na proudový režim
        self.use_streaming = self.file_size > memory_threshold 

    def iter_chunks(self, chunk_size: int = 8192):
        # Čtení a šifrování bloky
        ...

Řešení problému nonce: U AES-GCM a ChaCha20 opakování nonce s jedním klíčem je kritická zranitelnost. Derivace jedinečného nonce pro každý blok:

def _derive_block_nonce_12bit(base_nonce: bytes, block_index: int) -> bytes:
    # Prvních 8 bajtů — prefix, posledních 4 — čítač bloku
    prefix = base_nonce[:8]
    block_counter = block_index.to_bytes(4, byteorder='big')
    return prefix + block_counter

Bloky se čtou po 8 KB, nonce se generuje z základního nonce a indexu, zajišťující kryptografickou odolnost pro soubory jakékoli velikosti.

Odolnost proti selhání

Při výpadku napájení standardní šifrování s odstraněním původního souboru vede ke ztrátě dat. Implementovány mechanismy:

Google AdInline article slot
  • Soubor uzamčení .encryption_lock.json: Zaznamenává stav in_progress a seznam zpracovaných souborů.
  • Dočasné soubory .tmp: Šifrování do kopie, původní soubor se odstraní až po ověření.
  • Ověření integrity: Dešifrování bloku, porovnání HMAC a SHA-256 hashů.
  • Zpětné zpracování: Při přerušení – automatické obnovení původních souborů z zašifrovaných.

To zaručuje, že po výpadku jsou data buď plně zašifrovaná, nebo nedotčená.

Podporované algoritmy

  • AES-256-GCM: Hardwarové zrychlení AES-NI.
  • ChaCha20-Poly1305: Optimální bez AES-NI (ARM).
  • XChaCha20-Poly1305: 24-bajtové nonce pro velké objemy.

Paralelizace prostřednictvím ThreadPoolExecutor zrychluje I/O pro mnoho malých souborů, i přes GIL.

Důležité:

  • SecureBytes zabrání únikům klíčů prostřednictvím GC víceprůchodnou čistkou.
  • Proudové šifrování s jedinečnými nonce pro soubory >100 MB bez rizika kolizí.
  • Plná odolnost proti selhání: uzamčovací soubory a zpětné zpracování při výpadku.
  • Podpora AES-GCM, ChaCha20, XChaCha20 bez kompromisů v bezpečnosti.
  • Metadatový soubor .usb_crypt_meta.json, hesla minimálně 12 znaků s validací.

Omezení a threat model

Nástroj chrání proti ztrátě flashdisku, ale neukrývá jména souborů ani strukturu. Nechrání proti keyloggerům na hostitelském počítači. Určen pro střední a pokročilé vývojáře, kteří potřebují vlastní šifrování USB s důrazem na správu paměti a odolnost proti selhání.

— Editorial Team

Advertisement 728x90

Číst dál