Enligt konversationen i kommentarerna menar du hashing lösenord, inte kryptering lösenord. Du brukar göra detta med ett salt för att förhindra en regnbågsbordsattack. Att lagra lösenord som saltade hash är standarden för bästa praxis när det gäller att lagra lösenord i databaser.
Från och med version 3.2 har MongoDB inget inbyggt stöd för lösenordshasning som vissa SQL-databaser tillhandahåller, så du måste implementera det i Java.
Så här genererar du ett nytt konto eller ändrar lösenordet för ett befintligt konto:
- generera ett kryptografiskt säkert slumpmässigt saltvärde med
java.security.SecureRandom
. Den här klassen fungerar precis som den vanliga slumptalsgeneratorn code>java.util.Random (det är en underklass) men byter ut prestanda mot en mycket högre nivå av oförutsägbarhet, vilket krävs för ett säkerhetsrelevant sammanhang. - Skapa en sträng genom att sammanfoga salt och lösenord
- Generera en hash av den strängen med en kryptografiskt säker hashfunktion. Det finns många hash-funktioner som tillhandahålls av Java direkt, men du vill använda en som är avsiktligt svår att beräkna för att bromsa en angripare med databasåtkomst som försöker brute-force dina hash på deras lokala superdatorkluster. En bra kandidat är "PBKDF2WithHmacSHA1"-algoritmen som stöds av
javax.crypto.SecretKeyFactory
klass. - Spara dokumentet till MongoDB med fälten
användarnamn
,password_hash
ochpassword_salt
(plus dina faktiska applikationsdata, naturligtvis). Spara inte det ursprungliga lösenordet.
Så här hämtar du ett konto:
- Läs
username_input
ochpassword_input
den påstådda användaren angav i ditt inloggningsformulär. - Hämta dokumentet med
användarnamn
matcharusername_input
den angivna användaren. - Hämta
password_salt
fältet från det dokumentet - Skapa en sträng genom att sammanfoga
password_salt
ochpassword_input
precis som du gjorde tidigare. - Generera en hash av den strängen med samma kryptografiskt säkra hashfunktion.
- Jämför hashen med
lösenordshash
dokumentets fält. När det matchar angav användaren rätt lösenord.
Du kan alternativt bara hämta fälten password_hash och password_salt i dokumentet och inte ladda resten innan användaren är autentiserad, men jag skulle anta att det i den verkliga världen kommer att orsaka mer belastning än det skulle spara. Framgångsrika inloggningar kommer vanligtvis att vara betydligt fler än de misslyckade, såvida du inte har en angripare som försöker brute-force ett konto. Och i så fall skulle du blockera angriparen med fail2ban eller en annan inloggningsbegränsande mekanism.