Volgens het gesprek in de opmerkingen, bedoel je hashen wachtwoorden, niet versleutelen wachtwoorden. Meestal doe je dit met zout om een regenboogtafelaanval te voorkomen. Het opslaan van wachtwoorden als gezouten hashes is de best practice-standaard als het gaat om het opslaan van wachtwoorden in databases.
Vanaf versie 3.2 heeft MongoDB geen native ondersteuning voor wachtwoord-hashing zoals sommige SQL-databases bieden, dus je zult het in Java moeten implementeren.
Een nieuw account aanmaken of het wachtwoord van een bestaand account wijzigen:
- genereer een cryptografisch veilige willekeurige salt-waarde met
java.security.SecureRandom
. Deze klasse werkt net als de standaard generator voor willekeurige getallenjava.util.Random
(het is een subklasse) maar ruilt prestaties in voor een veel hoger niveau van niet-voorspelbaarheid dat vereist is voor een veiligheidsrelevante context. - Maak een string door salt en wachtwoord samen te voegen
- Genereer een hash van die string met een cryptografisch veilige hashfunctie. Java biedt out-of-the-box veel hash-functies, maar u wilt er een gebruiken die opzettelijk moeilijk te berekenen is om een aanvaller met databasetoegang te vertragen die uw hashes op hun lokale supercomputercluster brute kracht probeert te forceren. Een goede kandidaat is het "PBKDF2WithHmacSHA1"-algoritme dat wordt ondersteund door de
javax.crypto.SecretKeyFactory
klas. - Sla het document op in MongoDB met de velden
username
,password_hash
enpassword_salt
(plus uw werkelijke toepassingsgegevens natuurlijk). Bewaar het originele wachtwoord niet.
Om een account op te halen:
- Lees de
username_input
enpassword_input
de vermeende gebruiker heeft uw aanmeldingsformulier ingevuld. - Haal het document op waar de
username
komt overeen met deusername_input
de gebruiker heeft opgegeven. - Verkrijg het
password_salt
veld uit dat document - Maak een string door
password_salt
aan elkaar te koppelen enpassword_input
net zoals je eerder deed. - Genereer een hash van die string met dezelfde cryptografisch veilige hashfunctie.
- Vergelijk de hash met de
password_hash
veld van het document. Als het overeenkomt, heeft de gebruiker het juiste wachtwoord ingevoerd.
Je kunt ook alleen de velden password_hash en password_salt van het document ophalen en de rest niet laden voordat de gebruiker is geverifieerd, maar ik neem aan dat het in de echte wereld meer belasting zal veroorzaken dan het zou besparen. Succesvolle logins zullen meestal veel groter zijn dan de mislukte logins, tenzij je een aanvaller hebt die een account probeert te forceren. En in dat geval zou je de aanvaller blokkeren met fail2ban of een ander login-beperkend mechanisme.