# Šifrování: stavební kameny

Kryptografie vypadá zvenku jako jeden velký blok magie. Ve skutečnosti je to pár nástrojů, z nichž každý řeší jednu jedinou věc, a všechno ostatní — TLS, SSH, WireGuard, podepsané balíčky, šifrovaný disk — je jen jejich skládání.

Tahle stránka je mapa terénu. Ukazuje, co který nástroj umí, co neumí, a jak se z toho staví reálné protokoly. Podrobnosti jsou pak na samostatných stránkách.

Nepotřebuješ na to matematiku. Tam, kde se bez ní neobejdeme, je oddělená a označená.

## Čtyři vlastnosti, které chceš

Než začneš vybírat nástroje, musíš vědět, co po nich chceš. Bezpečnost není jedna vlastnost, jsou to čtyři a **každá se řeší jiným nástrojem**:

| Vlastnost | Otázka | Nástroj |
|---|---|---|
| **Důvěrnost** | Nepřečte to někdo po cestě? | šifra |
| **Integrita** | Nezměnil to někdo po cestě? | hash uvnitř MAC nebo podpisu |
| **Autenticita** | Mluvím s tím, s kým si myslím? | MAC nebo digitální podpis |
| **Nepopiratelnost** | Může to odesílatel později zapřít? | jen digitální podpis |

Nejčastější chyba začátečníka je myslet si, že první položka implikuje ostatní. **Neimplikuje.** Šifrovaný kanál bez ověření integrity jde po cestě přepisovat, i když útočník nevidí obsah — a u některých režimů šifer je to překvapivě snadné. Šifrovaný kanál bez autenticity ti nezaručí, že na druhém konci není útočník, který si s tebou šifruje sám.

Přesně proto TLS potřebuje certifikát a ne jen šifru. Viz [TLS a HTTPS](TLS-a-HTTPS).

## Symetrická šifra

Jeden klíč, kterým se šifruje i dešifruje. Obě strany ho musí mít.

```
otevřený text + klíč  →  šifra  →  šifrový text
šifrový text  + klíč  →  šifra  →  otevřený text
```

Je to rychlé. Moderní procesor s instrukcemi AES-NI zpracuje jednotky gigabajtů za sekundu na jádro, což je řádově víc, než uneseš po síti. **Veškerý objem dat v každém protokolu proto jede symetricky.** Asymetrická kryptografie se používá jen na to, aby se obě strany dohodly na tomhle jednom klíči.

### Které dvě šifry existují

V praxi potkáš dvě, obě jsou v pořádku:

**AES** (Rijndael, standard od roku 2001) — bloková šifra, pracuje po 16bajtových blocích. Klíč 128, 192 nebo 256 bitů. Prakticky každý procesor od roku 2010 ji umí hardwarově.

**ChaCha20** (Daniel J. Bernstein, 2008) — proudová šifra, klíč vždy 256 bitů. V softwaru je rychlejší než AES a hlavně **snáz se implementuje bez postranních kanálů**. Proto ji používají mobily bez AES akcelerace, [WireGuard](WireGuard) i většina novějších návrhů.

Všechno ostatní, co potkáš v návodech — DES, 3DES, RC4, Blowfish, IDEA, CAST — je buď prolomené, nebo tak pomalé a staré, že nemá smysl. Blowfish přežívá jedině uvnitř `bcrypt` na hesla, a to je jiné použití.

### Režim je důležitější než šifra

Bloková šifra sama umí zašifrovat jen 16 bajtů. Jak se z toho udělá šifrování souboru, určuje **režim** — a tady se dělají chyby, které skutečně bolí.

**ECB** — každý blok samostatně, stejný vstup dá stejný výstup. Katastrofa: struktura dat prosvítá skrz šifru. Klasická ukázka je obrázek tučňáka Tuxe zašifrovaný v ECB, kde je tučňák pořád dokonale vidět. ECB nepoužívej nikdy na nic.

**CBC** — každý blok se před šifrováním XORuje s předchozím šifrovým blokem, první s náhodným IV. Řeší problém ECB, ale sám o sobě neřeší integritu a jeho odstraňování zarovnání (padding) se dá zneužít k postupnému dešifrování dat útokem zvaným *padding oracle*. Odtud pochází POODLE i Lucky13.

**CTR** — z klíče a čítače se vyrobí proud bajtů, ten se XORuje s daty. Rychlé, paralelizovatelné, nepotřebuje zarovnání. Ale bez ochrany integrity je **triviálně přepisovatelné**: převrátíš-li bit v šifrovém textu, převrátí se přesně tentýž bit v otevřeném. Když víš, co tam je, přepíšeš to na cokoliv.

**AEAD** — režim, který šifruje **a zároveň ověřuje**. To je dnes jediná správná odpověď.

### AEAD: co chceš používat

*Authenticated Encryption with Associated Data.* Jedna operace, která dá šifrový text plus **ověřovací značku** (16 bajtů). Při dešifrování se značka kontroluje a když nesedí, operace **selže a nevydá nic** — místo aby ti vrátila poškozená data.

To „associated data" jsou metadata, která se nešifrují, ale jsou kryta značkou. Typicky hlavičky paketu: čísla portů musí být čitelná, ale nesmí se dát přepsat.

| Šifra | Kde ji potkáš |
|---|---|
| **AES-128-GCM**, **AES-256-GCM** | TLS 1.3, SSH, disky, prakticky všude |
| **ChaCha20-Poly1305** | TLS 1.3, [WireGuard](WireGuard), SSH, mobilní klienti |
| **AES-GCM-SIV** | tam, kde nejde zaručit unikátní nonce |
| **XChaCha20-Poly1305** | libsodium, `age` — 192bitový nonce, může být náhodný |

### Nonce se nesmí opakovat. Nikdy.

Tohle je nejdůležitější odstavec o symetrických šifrách.

Každé šifrování dostane kromě klíče ještě **nonce** (jinde IV nebo počáteční vektor) — číslo, které se pod jedním klíčem **nesmí objevit dvakrát**. Nemusí být tajné, klidně se posílá otevřeně. Musí být unikátní.

Když ho zopakuješ:

- U proudové šifry a CTR režimu dostaneš dva šifrové texty se stejným proudem. Jejich XOR je XOR obou otevřených textů a klíč k tomu není potřeba.
- U **AES-GCM** je to horší: opakovaný nonce umožní odvodit **ověřovací klíč**. Útočník pak umí padělat platné značky pro libovolná data a integrita je pryč úplně. Říká se tomu *forbidden attack* a takhle se v praxi rozbily reálné HTTPS servery s vadným generátorem.

GCM má nonce jen 96 bitů, takže náhodné generování je bezpečné jen do řádu miliard zpráv na klíč. Protokoly to proto řeší **čítačem** — TLS i WireGuard mají pořadové číslo paketu a klíč vymění dřív, než přeteče. Pokud tohle nemůžeš zaručit, sáhni po `AES-GCM-SIV` nebo `XChaCha20-Poly1305`, které opakování nonce přežijí bez katastrofy.

### Kolik bitů klíče

128 bitů je bezpečné a zůstane bezpečné. Vyzkoušet všechny klíče znamená 2¹²⁸ operací a to není „drahé", to je fyzikálně vyloučené — energie potřebná na pouhé odpočítání toho čísla převyšuje výkon Slunce nasměrovaný na planetu po staletí.

**AES-256 tedy nepotřebuješ na klasické útoky.** Používá se ze dvou důvodů: kvantový počítač by pomocí Groverova algoritmu efektivní sílu klíče zhruba půlil (viz [postkvantová kryptografie](Postkvantova-kryptografie)), a u dat, která mají zůstat tajná dvacet let, je ten dvojnásobek zadarmo. U šifrovaného disku a záloh dává AES-256 smysl. U TLS spojení je AES-128-GCM naprosto v pořádku.

## Asymetrická šifra

Dva klíče, které patří k sobě. Co udělá jeden, umí zvrátit jen ten druhý. Veřejný rozdáš, soukromý si necháš.

Řeší problém, který symetrická šifra vyřešit neumí: **jak se domluvit na klíči s někým, s kým jsi nikdy nemluvil, přes linku, kterou někdo poslouchá.**

Je řádově pomalejší než symetrická šifra, takže se používá jen na začátku spojení. Podrobně na stránce [veřejný a soukromý klíč](Verejny-a-soukromy-klic), samotná výměna klíče na [Diffie-Hellman](Diffie-Hellman).

## Hash

Funkce, která z libovolně velkého vstupu udělá krátký otisk pevné délky. Jednosměrná — z otisku se vstup nedá vypočítat.

Není to šifrování. **Hash se nedá vrátit zpátky ani se správným klíčem**, protože žádný klíč nemá. Slouží k porovnávání, ne k utajování.

Podrobně na [hashe, HMAC a podpisy](Hashe-a-podpisy).

## MAC: integrita se sdíleným klíčem

Hash sám o sobě nechrání před útočníkem. Kdo změní data, přepočítá i otisk.

**MAC** (message authentication code) je otisk, do kterého vstupuje tajný klíč. Bez klíče ho nikdo nespočítá, takže platný MAC dokazuje, že data pochází od někoho, kdo klíč zná — a že se cestou nezměnila.

Nejběžnější konstrukce je **HMAC**, kterou potkáš v podepsaných URL, v API tokenech, v JWT i uvnitř starších TLS. Modernější protokoly ji nepotřebují samostatně, protože ji mají zabalenou v AEAD šifře.

Rozdíl proti podpisu: MAC ověří kdokoliv, kdo zná klíč — a stejně tak ho kdokoliv, kdo zná klíč, umí vyrobit. **Nedokazuje tedy, kdo ze dvou stran zprávu vytvořil.** Na to potřebuješ podpis.

## KDF: jak se z jednoho tajemství udělá víc klíčů

Skoro nikdy nechceš použít surové tajemství přímo jako klíč. Z [Diffie-Hellmana](Diffie-Hellman) vypadne 32 bajtů, ale ty potřebuješ zvlášť klíč pro každý směr, zvlášť pro ověřování a chceš je umět po čase obměnit.

Na to je **KDF** — funkce odvození klíče. Ze vstupního tajemství a popisku vyrobí libovolný počet klíčů, které spolu nemají zjevnou souvislost.

Dvě rodiny, které se pletou:

**Pro vysoce náhodné vstupy** (výsledek DH, náhodná data) — **HKDF**. Je rychlá, protože nemusí nic ztěžovat: vstup už je nepředvídatelný. Tohle je „key schedule" v TLS 1.3.

**Pro hesla** (nízká entropie, lidé si vymýšlejí špatně) — **Argon2id**, `scrypt`, `bcrypt`, `PBKDF2`. Musí být **úmyslně pomalé a paměťově náročné**, aby útočník neuhádl deset miliard hesel za sekundu. Nikdy na hesla nepoužívej HKDF ani prostý SHA-256.

Podrobnosti na [hashe, HMAC a podpisy](Hashe-a-podpisy).

## Jak se z toho staví protokol

Tohle je nejužitečnější schéma na téhle stránce, protože ho beze změny najdeš v TLS, v SSH i ve WireGuardu:

```mermaid
sequenceDiagram
    participant K as Klient
    participant S as Server
    Note over K,S: 1. asymetricky se domluví na tajemství
    K->>S: veřejná část dočasného klíče
    S->>K: veřejná část dočasného klíče
    Note over K,S: obě strany spočítají totéž tajemství
    Note over K,S: 2. podpisem se ověří, s kým mluvím
    S->>K: certifikát / host key + podpis dosavadní komunikace
    K->>K: ověří podpis
    Note over K,S: 3. KDF odvodí symetrické klíče
    Note over K,S: 4. dál už jen AEAD, rychle a v obou směrech
    K->>S: šifrovaná data
    S->>K: šifrovaná data
```

Tomu se říká **hybridní šifrování** a je to jediný rozumný způsob. Asymetrická kryptografie na začátek, symetrická na provoz.

Ta trojka není detail: kdyby se šifrovaný provoz odvozoval přímo z DH tajemství bez KDF, nešly by odvodit oddělené klíče pro oba směry a šlo by přehrávat pakety zpátky odesílateli.

Krok 2 je ten, na který se zapomíná. **Samotná výměna klíčů tě nechrání před tím, kdo sedí uprostřed.** Detailně na [Diffie-Hellman](Diffie-Hellman).

## Kde to reálně teče

Srovnání, které ukazuje, že jde pořád o stejné čtyři nástroje:

| | TLS 1.3 | SSH | WireGuard |
|---|---|---|---|
| Výměna klíče | X25519 / ML-KEM hybrid | X25519 / ML-KEM hybrid | X25519 |
| Ověření protistrany | certifikát od [CA](Certifikaty-a-Lets-Encrypt) | host key, [TOFU](SSH) | veřejný klíč v konfiguraci |
| KDF | HKDF-SHA256 | SHA-2 | HKDF-BLAKE2s |
| Provoz | AES-GCM / ChaCha20-Poly1305 | AES-GCM / ChaCha20-Poly1305 | ChaCha20-Poly1305 |
| Výběr šifer | 5 možností | desítky | **žádný** |

Ten poslední řádek je záměrný. WireGuard nemá vyjednávání šifer vůbec — a tím se zbavil celé kategorie útoků, kde útočník donutí obě strany zvolit tu nejslabší společnou možnost (*downgrade*). Zaplatí za to tím, že při případném prolomení ChaCha20 se musí měnit protokol. Dnes se tomu říká *cryptographic agility* versus jednoduchost a v roce 2026 vyhrává jednoduchost.

## Bezpečnostní úroveň a délky klíčů

Bity klíče se mezi rodinami **nedají porovnávat přímo**. RSA s 2048 bity není osmkrát silnější než AES-256. Porovnává se přes společnou míru — kolik operací útok stojí:

| Úroveň | Symetrická | RSA / klasický DH | Eliptické křivky |
|---|---|---|---|
| 112 bitů | — | 2048 | 224–255 |
| **128 bitů** | **AES-128** | **3072** | **256** (X25519, P-256) |
| 192 bitů | AES-192 | 7680 | 384 |
| 256 bitů | AES-256 | 15360 | 512+ |

Odtud plyne to, co vidíš v praxi: **256bitová eliptická křivka odpovídá 3072bitovému RSA.** Proto má SSH klíč `ed25519` 32 bajtů a `rsa` 384 bajtů, a proto se všechno postupně stěhuje na křivky.

Tučný řádek je dnešní norma. RSA-2048 je na hranici a nové věci se na něm zakládat nemají, ale panika kvůli němu není namístě.

## Co doopravdy selhává

Statistika reálných průšvihů je tvrdohlavá: **algoritmy prakticky nikdy, okolí pořád.**

**Špatná náhodnost.** Debian v roce 2008 omylem osekal generátor v OpenSSL tak, že vznikalo jen 32 768 různých klíčů. Sony podepisovalo PlayStation 3 pořád stejným náhodným číslem a přišlo o podpisový klíč. Viz [náhodnost a entropie](Nahodnost-a-entropie).

**Neověřená protistrana.** Šifruješ dokonale, jenže s útočníkem.

**Vlastní implementace.** Časové rozdíly při porovnávání, chyby v aritmetice, neošetřené okrajové případy.

**Prostředí kolem.** Heartbleed byl přetečení bufferu, ne kryptografická chyba. `regreSSHion` byl souběh v obsluze signálu. Klíč zapomenutý v Gitu nepotřebuje lámat nikdo.

**Zastaralé nastavení.** Server, který stále nabízí TLS 1.0 nebo `ssh-rsa` se SHA-1.

Z toho plyne praktický závěr: čas věnuj správnému nastavení, aktualizacím a nakládání s klíči, ne výběru šifry.

## Pravidla, která se vyplatí

**Nepiš vlastní kryptografii.** Ani „jen to slepení". Používej `libsodium`, `age`, `rustls`, systémové OpenSSL nebo to, co má tvůj jazyk ve standardní knihovně.

**Nevymýšlej vlastní protokol.** Kombinace správných primitiv bývá špatná. Jsou to hotové protokoly (TLS, Noise, WireGuard), použij je.

**Nepoužívej `openssl enc` na skutečná data.** Nemá ověřenou integritu, výchozí odvození klíče z hesla je slabé a formát je nedokumentovaný. Na soubory je [`age`](Sifrovani-disku-a-souboru).

**Nikdy nepodepisuj ani nešifruj něco, čemu nerozumíš.** Podpisové klíče se dají zneužít k podpisu úplně jiného obsahu, když nekontroluješ, co ti přišlo pod ruku.

**Neporovnávej tajemství pomocí `==`.** Porovnání, které skončí na prvním odlišném bajtu, prozradí čas od času jeden bajt. Na to jsou funkce s konstantním časem (`hmac.compare_digest`, `sodium_memcmp`, `subtle.ConstantTimeCompare`).

**Šifrování není autorizace.** Že data umíš dešifrovat, neznamená, že je smíš číst. To řeší [autentizace a přístupová práva](Autentizace-pred-sluzbami).

## Časté omyly

**„Base64 je šifrování."** Není, je to kódování. Stejně tak URL-encoding, hex a ROT13. Nic z toho nemá klíč.

**„Hash se dá dešifrovat."** Nedá. Když ti to nějaká stránka „prolomí", jen prohledala tabulku už spočítaných hashů běžných hesel. Proto se hesla solí.

**„Delší klíč = větší bezpečnost."** RSA-8192 tě ochrání přesně stejně jako RSA-3072 a bude znatelně pomalejší. Za hranicí 128bitové úrovně přidáváš jen cenu.

**„Máme HTTPS, takže jsme v bezpečí."** HTTPS chrání data na cestě. Nechrání před SQL injection, únikem databáze, slabým heslem ani před tím, že ta data posíláš špatné službě.

**„Vlastní algoritmus je bezpečnější, protože ho nikdo nezná."** Utajení návrhu není bezpečnost. Kerckhoffsův princip z roku 1883 říká, že systém musí zůstat bezpečný, i když je o něm známo všechno kromě klíče. Všechno, co dnes používáš, je veřejné a po desetiletí veřejně lámané — právě proto mu můžeš věřit.

**„Kvantové počítače zítra prolomí všechno."** Prolomí asymetrickou část, ne symetrickou, a hybridní řešení už běží. Viz [postkvantová kryptografie](Postkvantova-kryptografie).

## Kam dál

- **[Veřejný a soukromý klíč](Verejny-a-soukromy-klic)** — asymetrická kryptografie, RSA, křivky, formáty klíčů
- **[Diffie-Hellman](Diffie-Hellman)** — jak se dva lidé domluví na tajemství přes veřejnou linku
- **[Hashe, HMAC a podpisy](Hashe-a-podpisy)** — otisky, hesla, elektronické podpisy
- **[Náhodnost a entropie](Nahodnost-a-entropie)** — nejčastější místo, kde se to v praxi láme
- **[SSH do hloubky](SSH)** — kompletní protokol od pozdravu po certifikáty
- **[TLS handshake krok za krokem](TLS-handshake)** — co si ty dvě strany doopravdy říkají
- **[Postkvantová kryptografie](Postkvantova-kryptografie)** — co se mění a co ne
- **[Šifrování disků a souborů](Sifrovani-disku-a-souboru)** — LUKS, age, zálohy
