Přeskočit na hlavní obsah

Ukládání hesel

  1. Ukládejte hesla tak, aby je útočník nezískal ani v případě napadení aplikace nebo databáze
  • Většina moderních jazyků a frameworků poskytuje funkce, které pomáhají hesla bezpečně ukládat
  • Útočník může brute forcovat hashe offline
  • Offline útoky je možné zpomalit výběrem takových hashovacích algoritmů, které jsou náročné na zdroje
  1. Použijte Argon2id s minimální konfigurací 15 MiB paměti, počtem iterací 2 a 1 stupněm paralelismu
  2. Použijte scrypt s parametrem minimálních nákladů na CPU / paměť 2^16, minimální velikostí bloků 8 (1024 bajtů) a stupněm paralelizace 1 v případě, že Argon2id není k dispozici
  3. Použijte work factor 10 nebo vyšší a limit 72 bajtů u starších systémů používajících bcrypt
  4. Použijte PBKDF2 s work factor 310.000 nebo vyšším a nastavte interní hashovací funkci HMAC-SHA-256, pokud není vyžadována FIPS-140
  5. Zvažte použití pepření k zajištění dodatečné in-depth ochrany (ačkoli sám o sobě neposkytuje žádné další bezpečné vlastnosti)

Background

Hashování vs šifrování

  • Hashování a šifrování jsou způsoby, jak udržet citlivá data v bezpečí
  • Hesla by měla být téměř za všech okolností zahashována, nikoli zašifrována
  • Heshování = jednosměrné, zahashovanou hodnotu nelze získat zpět (”dešifrovat” ji)
  • Hashování je vhodné pro ověřování hesel
  • I když útočník získá zahashované heslo, nemůže ho zadat do aplikace a přihlásit se
  • Šifrování = obousměrné, původní hodnotu lze po zašifrování znovu dešifrovat a získat zpět
  • Šifrování je vhodné pro ukládání dat (citlivých nebo osobních)
  • V souvislosti s hesly by se šifrování mělo používat pouze ojediněle, když je nutné získat původní heslo
    • Například pokud aplikace potřebuje heslo použít k ověření v jiném systému, který nepodporuje moderní způsob, jako je OpenID Connect
    • Použijte alternativní architekturu, aby se předešlo ukládání hesel v zašifrované podobě, pokud je to možné
  • Více informací najdete v OWASP cheat sheetu

Jak útočníci crackují hesla

  • Ačkoliv hesla není možné “dešifrovat”, je za určitých podmínek možné je “prolomit”
  1. Vyberte heslo, o kterém si myslíte, že ho oběť zvolila (např. myStrongPsw12_)
  2. Spočítejte jeho hash
  3. Porovnejte spočítaný hash s hashem oběti - pokud se shodují, “prolomili” jste heslo
  • Tento postup se opakuje pro velký počet hesel
  • K výběru těchto hesel lze použít různé metody
  1. Seznam hesel získaný z jiných napadených webů
  2. Brute force (zkoušení všech možných kandidátů)
  3. Slovník nebo seznam běžných hesel
  • Díky vysokorychlostnímu hardwaru (GPU) a cloudovým službám jsou náklady na úspěšné prolomení hesla relativně malé
  • Zejména nejsou-li dodrženy osvědčené postupy pro hashování
  • Hesla uložená pomocí moderních algoritmů a s využitím osvědčených postupů jsou pro útočníka prakticky neprolomitelná
  • Výběr moderního hashovacího algoritmu je zodpovědnost vývojáře

Koncepty pro ukládání hesel

Solení

  • Sůl (salt) = jedinečný, náhodně vygenerovaný řetězec, který se přidává ke každému heslu v rámci hashování
  • Protože je sůl pro každého uživatele jedinečná, musí útočník prolamovat hesla jedno po druhém pomocí příslušné soli
    • Místo, aby jednou vypočítal hash a porovnával je s každým uloženým hashem
  • Výrazně to ztěžuje prolomení velkého počtu hashů - potřebný čas roste přímo úměrně s počtem hashů
  • Solení chrání před útočníkem, který předem vypočítá hashe nebo je vyhledá v databázi
  • Díky solení není možné zjistit, zda mají dva uživatelé stejné heslo
  • Moderní hashovací algoritmy jako jsou Argon2id, bcrypt a PBKDF2, automaticky hesla solí
    • Při jejich použití nejsou potřeba žádné další kroky

Pepření

  • Kromě solení lze použít i pepření (peppering)
  • Jeho účelem je zabránit útočníkovi, aby byl schopen prolomit některý z hashů - pokud má přístup k databázi, zmocnil se jí, využil SQL injection atp.
  • Jednou ze strategií je hashování hesel a následné šifrování symetrickým klíčem nebo HMAC před uložením (klíč funguje jako pepř)
  • Strategie nijak neovlivňuje funkci hashování hesel
  • Pepř je sdílený mezi uloženými hesly a není jedinečný jako sůl
  • Na rozdíl od soli by pepř neměl být uložen v databázi
  • Pepř je secret, takže by měl být uložený ve vaultu nebo HSM (Hardware Security Modules)
  1. Zvažte strategii rotace klíče stejně jako u jiných kryptografických klíčů

Work factors

  • Počet iterací hashovacího algoritmu, které se provedou pro každé heslo
    • Obvykle 2^(počet iterací)
  • Účelem je učinit výpočet hashe nákladnějším, což snižuje rychlost a zvyšuje útočníkovi náklady v případě, že se pokusí heslo prolomit
  • Work factor je často uložen ve výstupu hashe
  • Při výběru je potřeba najít rovnováhu mezi bezpečností a výkonem
  • Vyšší work factors ztíží prolomení hashe, ale také zpomalí proces přihlašování
  • Pokud je work factor příliš vysoký, může se snížit výkon aplikace a útočník by to mohl využít k DoS útoku provedením velkého počtu pokusů o přihlášení, čímž vyčerpá CPU serveru
  • Neexistuje žádné zlaté pravidlo - závisí na výkonu a počtu uživatelů aplikace
  • Určení optimálního work faktoru bude znamenat experimentování
  • Výpočet hashe by měl trvat méně než jednu sekundu

Upgrade work faktoru

  • Lze jej v průběhu času zvyšovat s tím, jak se hardware stává výkonějším a levnějším
  • Nejlepším přístupem je počkat, až se uživatel přihlásí a po úspěšném pokusu znovu zahashovat jeho heslo s novým work faktorem
  • Různá hesla tedy budou mít různé work factors
  • V závislosti na aplikaci může být vhodné odstranit starší hashe a vyžadovat, aby uživatelé při příštím přihlášení svá hesla obnovili, aby se zabránilo ukládání starších a méně bezpečných hashů

Hashovací algoritmy

  • Moderní hashovací algoritmy jsou pomalé, oproti algoritmům jako je SHA1 nebo MD5, které byly navrženy jako rychlé
  • Jejich pomalost závisí na work faktoru
  • Webové stránky by neměly skrývat, jaký algoritmus používají
  • Pokud používáte moderní algoritmus, mělo by být bezpečné je veřejně uvést

Argon2id

  • Argon2 je vítěz soutěže Password Hashing Competition 2015
  • Algoritmus má tři verze, ale používat by se měla verze Argon2id
  • Jako minimum by měla být použita jedna z následujících konfigurací, která zahrnuje velikost paměti (m), minimální počet iterací (t) a stupeň paralelismu (p)
    • m=37 MiB, t=1, p=1
    • m=15 MiB, t=2, p=1
  • Obě nastavení jsou rovnocenné z hlediska ochrany, kterou poskytují
  • Jediným rozdílem je kompromis mezi využitím procesoru a RAM

scrypt

  • scrypt je funkce pro odvozování klíčů na základě hesla
  • Nové systémy by vždy měly zvážit Argon2id, ale ve starších systémech se hodí právě scrypt
  • Jako minimum by se měla použít jedna z následujících konfigurací, která zahrnuje parametr minimálních nákladů na procesor / paměť (N), velikost bloku (r) a stupeň paralelismu (p)
    • N=2^16 (64 MiB), r=8 (1024 bytes), p=1
    • N=2^15 (32 MiB), r=8 (1024 bytes), p=2
    • N=2^14 (16 MiB), r=8 (1024 bytes), p=4
    • N=2^13 (8 MiB), r=8 (1024 bytes), p=8
    • N=2^12 (4 MiB), r=8 (1024 bytes), p=15
  • Obě nastavení jsou rovnocenné z hlediska ochrany, kterou poskytují
  • Jediným rozdílem je kompromis mezi využitím procesoru a RAM

bcrypt

  • bcrypt by měla být hned druhou volbou pokud není k dispozici Argon2id

Limity

Pre-hashing hesel

  • Alternativním přístupem je pre-hashování hesla pomocí rychlého algoritmu (SHA-256) a následné zahashování tohoto hashe
bcrypt(base64(hmac-sha256(data:$password, key:$pepper)), $salt, $cost)
  • Jde o nebezpečný (ale běžný) postup
  • Je třeba se mu vyhnout z důvodu password shucking a dalších problémů spojených s kombinací bcrypt a jiných funkcí

PBKDF2

  • PBKDF2 je doporučován NISTem a jeho implementace je ověřena systémem FIPS-140
  • Měl by být upřednostňovaným algoritmem, pokud jsou tyto algoritmy vyžadovány
  • PBKDF2 vyžaduje zvolení hashovacího algoritmu
  • HMAC-SHA-256 je doporučován NISTem
  • Work factor je implementován prostřednictvím počtu iterací, které by měly být nastaveny odlišně v závislosti na použitém hashovacím algoritmu
    • PBKDF2-HMAC-SHA1: 720 000 iterací
    • PBKDF2-HMAC-SHA256: 310 000 iterací
    • PBKDF2-HMAC-SHA512: 120 000 iterací
  • Obě nastavení jsou rovnocenné z hlediska ochrany, kterou poskytují
  • Heslo bude automaticky přehashováno, pokud je funkce použita s HMAC a heslo je delší než velikost bloku funkce
  • Dobrá implementace provede tento krok před nákladnou iterační fází
  • Některé implementace však provádějí konverzi při každé iteraci
  • To způsobuje, že hashování dlouhých hesel je výrazně dražší než hashování krátkých hesel
  • Existuje zde potenciální DoS zranitelnost (jako např. v Djangu roku 2013)

Upgrade starších hashů

  • V případě aplikací používajících starší, méně bezpečné hashe (MD5, SHA-1), by tyto hashe měly být aktualizovány na moderní algoritmy, jako je popsáno výše
  • Při dalším zadávání hesla uživatelem (obvykle při přihlašování), by mělo být heslo znovu zahashováno moderním algoritmem
  • Dobrým postupem je také vypršení platnosti aktuálního hesla a požadování nového po expiraci
  • Tento přístup však znamená, že stará hesla budou uložena v databázi, dokud se uživatel znovu nepřihlásí
  • Tomu se jde vyhnout následovně
    • Použití stávajících hashů jako vstupů pro bezpečnější algoritmy md5($password)bcrypt(md5($password))
      • Vrstvením hashů se vyhnete znalosti původního hesla
      • Tento přístup může usnadnit prolomení hesel
      • Tyto hashe by měly být při příštím přihlášení nahrazeny přímými hashi
    • Ujistěte se, že upgrade hashovacího algoritmu je co nejjednodušší
    • Počítejte s kombinací starých a nových hesel pro přechodné období
    • Použití kombinace algoritmů hashování je snazší, pokud jsou algoritmus a work factor uloženy spolu s heslem (např. PHC řetězci)

Mezinárodní znaky

  • Ujistěte se, že je hashovací knihovna schopna přijímat širokou škálu znaků a je kompatibilní se všemi kódovými znaky Unicode
  • Uživatelé by měli mít možnost používat celou škálu znaků, které jsou na moderních zařízeních k dispozici
  • Měli by mít možnost vybírat hesla z rýzných jazyků a piktogramů
  • Snižte entropy před hashováním uživatelského hesla
  • Hashovací knihovny musí být schopny přijímat NULL bajt

Kam dál

Zranitelnosti

Checklisty