-
Notifications
You must be signed in to change notification settings - Fork 0
Verejny a soukromy klic
Asymetrická kryptografie je nejméně intuitivní věc v celé síťařině. Symetrická šifra dává smysl každému — máme společné heslo, tak si šifrujeme. Ale představa, že si můžeme vyměnit klíče veřejně, před zraky útočníka, a přesto se domluvit na tajemství, vypadá na první pohled jako podvod.
Není. Tahle stránka vysvětluje, jak to funguje, kde je to v praxi vidět a co s klíči doopravdy dělat.
Základní pojmy jsou na stavebních kamenech, samotná výměna klíčů na Diffie-Hellman.
Máš dvojici klíčů, které vzniknou najednou a patří k sobě:
Soukromý klíč — jediná kopie, nikdy neopustí tvůj stroj. Z něj se dá spočítat veřejný klíč.
Veřejný klíč — rozdáš ho komukoliv. Klidně ho pověsíš na web. Ze znalosti veřejného klíče nejde odvodit soukromý — tohle je celá pointa a stojí na tom, že určité matematické operace se snadno počítají jedním směrem a prakticky nedají zvrátit.
Z toho plynou dvě různé operace, které se často pletou:
| Operace | Kdo použije soukromý | Kdo použije veřejný | K čemu |
|---|---|---|---|
| Šifrování | příjemce dešifruje | odesílatel šifruje | důvěrnost |
| Podpis | autor podepisuje | kdokoliv ověří | autenticita |
Všimni si, že jsou to opačné směry. Když chceš někomu poslat tajnou zprávu, potřebuješ jeho veřejný klíč. Když chceš dokázat, že zpráva je od tebe, použiješ svůj soukromý klíč.
flowchart LR
subgraph sif [Šifrování]
A[Zpráva] -->|veřejný klíč Boba| B[Šifrový text]
B -->|soukromý klíč Boba| C[Zpráva]
end
subgraph pod [Podpis]
D[Zpráva] -->|soukromý klíč Alice| E[Podpis]
E -->|veřejný klíč Alice| F[platí / neplatí]
end
Tuhle větu najdeš ve stovkách návodů a je nesprávná. Vypadá pravdivě jen u RSA, protože jeho matematika je symetrická. U eliptických křivek — tedy u toho, co dnes používáš — je podpis úplně jiný algoritmus než šifrování a takové srovnání nedává smysl vůbec.
Správně: podpis a šifrování jsou dvě samostatné schopnosti. Některé rodiny umí obojí (RSA), některé jen jednu (ECDSA a Ed25519 umí jen podepisovat, X25519 umí jen výměnu klíčů).
Není potřeba počítat, ale bez téhle intuice zůstane všechno magie. Existují matematické operace, které jsou snadné jedním směrem a extrémně drahé zpátky:
Násobení versus rozklad na součin. Vynásobit dvě tisícimístná prvočísla umí telefon okamžitě. Dostat je z výsledku zpátky nikdo neumí. Na tom stojí RSA.
Umocňování ve zbytkové aritmetice versus diskrétní logaritmus. Spočítat g^a mod p je snadné. Dostat z výsledku a je nezvládnutelné. Na tom stojí klasický Diffie-Hellman a DSA.
Násobení bodu na eliptické křivce versus totéž zpátky. Sečíst bod sám se sebou a-krát je rychlé. Zjistit z výsledku a je řádově těžší než u předchozích. Na tom stojí ECDH, ECDSA a Ed25519.
To „extrémně drahé" má konkrétní čísla. Rozklad 2048bitového čísla je mimo dnešní možnosti kohokoliv na planetě. Rozklad 512bitového šel v roce 1999 a dnes to zvládne cloudová instance za pár hodin — proto se délky klíčů posouvají.
Zásadní upozornění: žádná z těch tří věcí není dokázaná jako těžká. Jen to nikdo padesát let nedokázal zlomit. To je slabší tvrzení, než jak se obvykle prezentuje, a je to důvod, proč se kryptografie umí měnit.
Rozdíl je v tom, jak dobře fungují nejlepší známé útoky.
Na RSA a klasický DH existuje síto v číselném tělese — algoritmus, který sice trvá dlouho, ale roste podexponenciálně. Zdvojnásobení délky klíče proto sílu nezdvojnásobí, jen o kus přidá.
Na eliptických křivkách nic lepšího než obecné metody (Pollardovo rho) nikdo nenašel. Ty trvají zhruba odmocninu z velikosti skupiny, což je plně exponenciální v délce klíče. Každý přidaný bit klíče tedy stojí útočníka dvojnásobek.
Praktický důsledek:
| RSA-3072 | P-256 / X25519 | |
|---|---|---|
| Bezpečnostní úroveň | 128 bitů | 128 bitů |
| Veřejný klíč | ~400 B | 32 B |
| Podpis | 384 B | 64 B |
| Generování klíče | sekundy | milisekundy |
| Podepsání | rychlé | rychlé |
| Ověření podpisu | velmi rychlé | rychlé |
RSA má jedinou přetrvávající výhodu: ověření podpisu je díky malému veřejnému exponentu (65537) mimořádně levné. Proto se pořád drží tam, kde se jeden podpis ověřuje milionkrát. Jinak nemá důvod.
Nejstarší (1977) a nejrozšířenější. Umí jako jediný z běžných algoritmů podepisovat i šifrovat.
openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:3072 -out rsa.pem
openssl pkey -in rsa.pem -pubout -out rsa.pub
openssl pkey -in rsa.pem -text -noout | headPravidla, pokud RSA používat musíš:
- Minimálně 2048 bitů, raději 3072. Pod 2048 nic. Nad 4096 jen plýtváš výkonem.
- Zarovnání OAEP pro šifrování, nikdy PKCS#1 v1.5. Ten má útok, který se pod různými jmény (Bleichenbacher, ROBOT) vrací každých pár let.
- Zarovnání PSS pro podpisy, kde to protistrana umí.
RSA neumí zašifrovat velká data. Ta zpráva se musí vejít do klíče minus zarovnání — u 2048bitového klíče s OAEP a SHA-256 je to 190 bajtů. Proto se v reálu RSA nikdy nešifruje obsah, jen se jím přenese symetrický klíč. Tomu se říká key transport a TLS 1.3 ho úplně zrušilo, protože nemá dopředné utajení.
prime256v1 / secp256r1 a secp384r1. Standardní, všude podporované, používané ve většině certifikátů.
Jsou v pořádku, ale implementují se hůř — jsou u nich potřeba kontroly platnosti bodu, převody souřadnic a snadno vzniknou postranní kanály. Navíc jsou u nich neveřejně zvolené konstanty, což od roku 2013 živí trvalou nedůvěru.
Návrh z roku 2005, dnes výchozí volba. Jedna křivka, dvě použití, která se nedají zaměňovat:
X25519 — výměna klíčů (ECDH). Používá ji TLS 1.3, SSH i WireGuard. Veřejný klíč 32 bajtů, sdílené tajemství 32 bajtů.
Ed25519 — podpisy (EdDSA). Používá ji SSH, podepisování Git commitů, age, moderní balíčkovací systémy. Veřejný klíč 32 bajtů, podpis 64 bajtů.
Proč je to lepší než P-256:
- Všechny konstanty jsou odvozené a vysvětlené. Nic není „prostě zvolené".
- Nemá okrajové případy. Jakýchkoliv 32 bajtů je platný veřejný klíč, takže nejde poslat záludný vstup.
- Implementace je přirozeně v konstantním čase, takže postranní kanály nevznikají mimoděk.
- Ed25519 je deterministické. Náhodné číslo pro podpis se odvodí z klíče a zprávy, ne z generátoru. Tím odpadá nejhorší selhání ECDSA — viz níže.
ECDSA potřebuje ke každému podpisu jednorázové náhodné číslo k. Když se k zopakuje u dvou různých zpráv, dá se ze dvou podpisů přímo dopočítat soukromý klíč. Ne oslabit, přímo spočítat.
Není to teorie:
-
Sony PlayStation 3 (2010) používalo pro všechny podpisy pevné
k. Podpisový klíč konzole byl veřejně odvozen a nešel opravit, protože byl v hardwaru. - Android (2013) měl vadný generátor náhodných čísel a z peněženek Bitcoinu tak zmizely reálné peníze.
Ed25519 tenhle problém nemá z podstaty návrhu. Když si vybíráš a máš na výběr, ber Ed25519.
DSA — 1024bitové omezení, stejná past s k, dnes nemá jediný důvod existovat. OpenSSH ho v roce 2024 vypnul a v roce 2025 z kódu odstranil.
RSA se SHA-1 (ssh-rsa) — OpenSSH ho vypnul ve verzi 8.8. Když ti staré zařízení hlásí no matching host key type, je to tohle. Řešením je zařízení aktualizovat, ne obcházet.
secp256k1 — křivka Bitcoinu. Je v pořádku, ale mimo kryptoměny nemá důvod.
Jeden a tentýž klíč potkáš ve čtyřech zápisech a je užitečné vědět, který je který.
PEM — textový, -----BEGIN ... -----, obsah je base64. Nejběžnější u TLS.
-----BEGIN PRIVATE KEY----- ← PKCS#8, moderní, jakýkoliv algoritmus
-----BEGIN RSA PRIVATE KEY----- ← PKCS#1, jen RSA, staré
-----BEGIN EC PRIVATE KEY----- ← SEC1, jen křivky, staré
-----BEGIN OPENSSH PRIVATE KEY----- ← formát OpenSSH, ne OpenSSL
-----BEGIN CERTIFICATE----- ← to není klíč, to je certifikát
DER — totéž binárně, bez base64. Používá Java a Windows, přípona .der nebo .cer.
PKCS#12 / PFX — jeden soubor .p12 obsahující klíč i certifikát i řetěz, chráněný heslem. Windows, Java, importy do prohlížeče.
Formát OpenSSH — ~/.ssh/id_ed25519. Vlastní formát, který se od OpenSSL liší a od verze 7.8 je výchozí. Umí soukromý klíč chránit heslem přes bcrypt_pbkdf, což ho dělá odolnějším proti hádání hesla než starý formát.
Převody, které budeš dřív nebo později potřebovat:
# PEM → DER
openssl pkey -in key.pem -outform DER -out key.der
# starý PKCS#1 → moderní PKCS#8
openssl pkey -in old-rsa.pem -out new.pem
# klíč + certifikát → PKCS#12
openssl pkcs12 -export -inkey key.pem -in cert.pem -certfile chain.pem -out bundle.p12
# PKCS#12 → PEM
openssl pkcs12 -in bundle.p12 -nodes -out all.pem
# SSH veřejný klíč z privátního (když ho ztratíš)
ssh-keygen -y -f ~/.ssh/id_ed25519 > ~/.ssh/id_ed25519.pubChyba, která se stane každému: zaměnit certifikát a klíč. Certifikát je veřejný a začíná BEGIN CERTIFICATE. Klíč je tajný a začíná BEGIN ... PRIVATE KEY. Nginx si na to bude stěžovat větou PEM_read_bio_X509 a nebude vysvětlovat proč.
# typ a parametry klíče
openssl pkey -in key.pem -text -noout
# patří tenhle klíč k tomuhle certifikátu?
openssl pkey -in key.pem -pubout | openssl sha256
openssl x509 -in cert.pem -pubkey -noout | openssl sha256
# obě čísla musí být stejná
# co je v certifikátu
openssl x509 -in cert.pem -noout -subject -issuer -dates -ext subjectAltName
# SSH klíč: typ, délka a otisk
ssh-keygen -lf ~/.ssh/id_ed25519.pubTo porovnání otisků je nejrychlejší způsob, jak vyloučit nejčastější příčinu toho, že server po výměně certifikátu nenaběhne.
Veřejné klíče se špatně porovnávají očima. Proto se z nich dělá otisk — hash veřejného klíče, který se dá přečíst do telefonu.
ssh-keygen -lf ~/.ssh/id_ed25519.pub
# 256 SHA256:5N3Yb... martin@notebook (ED25519)Otisk nenahrazuje ověření, jen ho zkracuje. Když otisk získáš tou samou cestou, kterou by šel útočník, nedokázal jsi nic. Tohle je celý problém prvního připojení na SSH server, podrobně na SSH.
Historicky se používal MD5 (ssh-keygen -E md5) a u nich ta dvojtečkovaná šestnáctková čísla. Dnes SHA-256 v base64.
| Situace | Kdo má soukromý klíč | Co dokazuje |
|---|---|---|
| HTTPS | server | že web patří tomu, komu CA vystavila certifikát |
| SSH — host key | server | že jsi u toho stroje jako minule |
| SSH — klíč uživatele | ty | že jsi ten, kdo má klíč v authorized_keys
|
| mTLS | obě strany | vzájemně; vyžaduje vlastní CA |
| WireGuard | oba peery | že protistrana zná klíč z konfigurace |
| Podpis balíčků APT | správce repozitáře | že balíček nikdo nepodstrčil |
| Podpis Git commitu | autor | kdo commit vytvořil |
| Passkey | tvoje zařízení | přihlášení bez hesla |
Podstatné je, že ve všech případech jde o totéž. Naučíš se to jednou.
Veřejný klíč sám o sobě neříká, komu patří. Certifikát je veřejný klíč plus jméno plus doba platnosti, to celé podepsané někým, komu se dá věřit.
certifikát = { veřejný klíč, jména (SAN), platnost od–do, účel }
+ podpis certifikační autority přes to všechno
Když prohlížeč certifikát dostane, ověří podpis veřejným klíčem té CA — a její certifikát ověří proti další, až ke kořenu, který má v systému.
Certifikát tedy nezvyšuje sílu šifrování ani o bit. Řeší výhradně otázku, komu klíč patří.
Soukromý klíč se negeneruje jinde, než kde bude použitý. Když ti někdo pošle klíč mailem, není to tvůj klíč, je to sdílený klíč.
Nikdy ho neposílej. Ani sobě, ani do chatu, ani do repozitáře. Když se to stane, klíč je spálený a musí se vyměnit — smazání commitu nestačí, historie zůstává.
Chraň ho heslem. U SSH:
ssh-keygen -t ed25519 -a 100 -C "martin@notebook"-a 100 je počet kol funkce odvození klíče z hesla. Zpomalí to hádání hesla, kdyby se soubor ztratil, a při přihlašování to nepoznáš. Aby tě heslo neotravovalo, je ssh-agent.
Práva 600. OpenSSH klíč s právy pro skupinu odmítne použít a udělá dobře.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pubRůzné klíče na různé účely. Jeden pro server doma, jiný pro práci, jiný pro GitHub. Ztráta jednoho pak neznamená ztrátu všeho a odebrat jeden přístup je jeden řádek.
Nejlepší je klíč, který nejde zkopírovat. Hardwarový token (YubiKey, Nitrokey) drží soukromý klíč uvnitř čipu a operaci provádí sám. Malware ti ho nemůže ukrást, protože se nikdy neobjeví v paměti. OpenSSH to podporuje od verze 8.2:
ssh-keygen -t ed25519-sk -O resident -O verify-requiredVznikne klíč, který vyžaduje dotek tokenu u každého přihlášení a verify-required k tomu přidá PIN. resident znamená, že klíč lze z tokenu obnovit na novém počítači (ssh-keygen -K). Za devět stovek je tohle největší skok v bezpečnosti, jaký si můžeš koupit.
Měj plán na výměnu. Předem věz, jak by ses dostal na server, kdyby ti notebook shořel. Druhý klíč v trezoru, konzole u poskytovatele, přístup přes VPN z jiného stroje.
Nemusíš na to GPG. SSH klíč, který už máš, to umí od OpenSSH 8.0:
# podepsat
ssh-keygen -Y sign -f ~/.ssh/id_ed25519 -n file dokument.pdf
# vznikne dokument.pdf.sig
# ověřit — potřebuješ seznam povolených podepisujících
echo "martin@example.cz $(cat ~/.ssh/id_ed25519.pub)" > allowed_signers
ssh-keygen -Y verify -f allowed_signers -I martin@example.cz \
-n file -s dokument.pdf.sig < dokument.pdfStejným mechanismem se podepisují Git commity, bez GPG a bez keyserverů:
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519.pub
git config --global commit.gpgsign true- Diffie-Hellman — jak se dvě strany domluví na společném tajemství
- Hashe, HMAC a podpisy — co se vlastně podepisuje
- SSH do hloubky — nejčastější místo, kde tyhle klíče použiješ
- Vlastní certifikační autorita — když si chceš certifikáty vystavovat sám
- Náhodnost a entropie — proč se klíče lámou
Našel jsi chybu nebo něco chybí? Založ issue nebo pošli pull request. — Psáno 2026, licence CC BY-SA 4.0
Základy
- Cesta paketu
- Vrstvy a zapouzdření
- MAC, ARP a přepínání
- Prefixy a masky
- Směrování
- DHCP a DNS
- Porty a spojení
- NAT a port forwarding
Domácí síť
IPv6
Linux firewall
TLS a reverse proxy
- TLS a HTTPS
- HTTP, QUIC a WebSocket
- Reverse proxy
- Caddy
- Nginx
- Traefik
- Certifikáty a Let's Encrypt
- Vlastní certifikační autorita
Kryptografie
- Stavební kameny
- Veřejný a soukromý klíč
- Diffie-Hellman
- Hashe, HMAC a podpisy
- Náhodnost a entropie
- TLS handshake
- Postkvantová kryptografie
- Šifrování disků a souborů
Virtualizace a kontejnery
Diagnostika
Vzdálený přístup
Provoz a bezpečnost
Praxe