Podle konverzace v komentářích máte na mysli hašování hesla, nikoli šifrování hesla. Obvykle byste to udělali se solí, abyste zabránili útoku na duhový stůl. Ukládání hesel jako osolených hashů je nejlepším standardem, pokud jde o ukládání hesel v databázích.
Od verze 3.2 nemá MongoDB žádnou nativní podporu pro hašování hesel, jako poskytují některé databáze SQL, takže jej budete muset implementovat v Javě.
Chcete-li vygenerovat nový účet nebo změnit heslo stávajícího účtu:
- vygenerujte kryptograficky zabezpečenou náhodnou hodnotu soli pomocí
java.security.SecureRandom
. Tato třída funguje stejně jako standardní generátor náhodných číseljava.util.Random
(je to podtřída), ale vyměňuje výkon za mnohem vyšší úroveň nepředvídatelnosti, která je vyžadována pro kontext relevantní pro zabezpečení. - Vytvořte řetězec zřetězením soli a hesla
- Vygenerujte hash tohoto řetězce pomocí kryptograficky zabezpečené hašovací funkce. Existuje mnoho hašovacích funkcí, které Java poskytuje přímo z krabice, ale chcete použít tu, která je záměrně obtížně vypočítatelná, abyste zpomalili útočníka s přístupem k databázi, který se snaží hrubou silou vynutit vaše haše na jejich místním clusteru superpočítačů. Dobrým kandidátem je algoritmus "PBKDF2WithHmacSHA1", který je podporován
javax.crypto.SecretKeyFactory
třída. - Uložte dokument do MongoDB pomocí polí
username
,password_hash
apassword_salt
(plus vaše skutečná data aplikace, samozřejmě). Neukládejte původní heslo.
Chcete-li získat účet:
- Přečtěte si
username_input
apassword_input
údajný uživatel zadal do vašeho přihlašovacího formuláře. - Načtěte dokument, kde je
username
odpovídáusername_input
poskytnutý uživatelem. - Získejte
password_salt
pole z tohoto dokumentu - Vytvořte řetězec zřetězením
password_salt
apassword_input
stejně jako vy. - Vygenerujte hash tohoto řetězce pomocí stejné kryptograficky zabezpečené hašovací funkce.
- Porovnejte hodnotu hash s hodnotou
password_hash
pole dokumentu. Když se shoduje, uživatel zadal správné heslo.
Alternativně byste mohli načíst pouze pole password_hash a password_salt dokumentu a nenačítat zbytek před ověřením uživatele, ale předpokládal bych, že v reálném světě to způsobí větší zatížení, než by to ušetřilo. Úspěšné přihlášení obvykle výrazně převýší počet neúspěšných, pokud nemáte útočníka, který se pokusí brutálně vynutit účet. A v takovém případě byste útočníka zablokovali pomocí fail2ban nebo jiný mechanismus omezující přihlášení.