Door
Martijn L
op 04-12-2012 18:52
gewijzigd op 04-12-2012 19:15
2.413 views
Hallo,
Nadat ik opzoek was voor een oplossing op mijn vraag ben ik op iets totaal anders beland.
Ik heb een script met de daarbij behorende reacties gelezen.
Hieruit kwam ik tot de conclusie dat ik mijn wachtwoorden beter moet beveiligen.
Ik heb gister een dagje vele scripts, tuts, topics van hier en op andere sites doorgelezen.
De link van iemand van hier vond ik best informatief.
Overigens gebruik ik nu nog
md5("$pass"."8y2gu&hr*5e%l");
@John Berg geeft bewijs dat de veiligheid van een wachtwoord vaak een breekpunt is, voor het kraken van md5.
Toch ben ik overtuigd dat ik mijn wachtwoordbeveiliging iets moet aanscherpen.
Nu over op de vraag:
In de tutorial wordt een manier van een unieke salt functie voor iedere gebruiker gemaakt.
Hoe wordt deze opgeslagen of onthouden?
Kan je dit in de database als PlainTxt neerzetten?
Een andere link uit dat topic geeft weer dat sha512(); sterk genoeg is.
Sorry, ik zie nu dat 'Tut' het gebruik van Blowfisch al bespreekt. Zij gebruiken de username als salt, en die staat natuurlijk ook gewoon in de database. Dat is makkelijk, maar in 'Topic' wordt juist gesteld dat het een goed idee is om de salt NIET in de database te hebben.
In 'Link2' gebruiken ze een random number generator om het salt te genereren. Lekker random natuurlijk, maar:
self.password = '$'.join((algo, salt, hsh))
Ik kan geen python, maar ik heb toch zo'n donkerbruin vermoeden dat dit overeen komt met PHP:
Als ik het goed zie slaan ze de salt gewoon onversleuteld in de database op! Zo lang de hackers dit niet weten gaan ze natuurlijk niets hebben aan een rainbow table. Maar wat als ze het wel weten - beveiliging door middel dan iets waarvan je maar moet hopen dat niemand het weet, heette dat niet 'security by obscurity'? En die scheidingsteken ($) dat wekt misschien een vermoeden. Zijn er in de loop van de tijd verschillende hash algos gebruikt dan hangen waardes in het eerste deel samen met de lengtes van het derde deel. Dan wordt het volgens mij toch een stuk makkelijker om te raden wat het tweede deel is.
En dan is er nog een ander probleempje: de random number generators van PHP zijn niet zo sterk als urandom. En die random numbers worden ergens anders misschien weer gebruikt voor beveiliging, bijvoorbeeld tegen Cross Site Request Forgery. Door ze ongehasht in de database op te slaan zou je eventuele hackers die ze bijvoorbeeld via SLQ injection kunnen zien dus ook nog eens kunnen helpen om die andere beveiliging te omzeilen.
Wat ik zou doen is zowel een vast salt gebruiken dat in de configuratie van de applicatie moet worden ingesteld, als een variabel salt gebruiken, wat vrees ik toch in de database zal moeten staan. Eventueel eerst het variabele salt hashen samen met het vaste, zodat het voor hackers lastiger is om er achter te komen in welk(e) veld(en) de variabele salt staat (OK, dit is ook obscurity, maar er is toch een flinke kans dat hackers de broncode niet kennen en proberen om het te raden obv de data). En dan de wachtwoord samen het gecombineerde gehashte salt.
Maar persoonlijk ben ik er nog niet uit wat nu optimaal is. Wel weet ik dat de OWASP guide aanraadt om een framework te gebruiken en niet je eigen authorization te schrijven (bron. Maar dat is wellicht geen oplossing als je zelf een framework onderhoudt ;-).
Verder mis ik in de meeste tutorials etc. voorzieningen om te proberen om hackpogingen te detecterten:
"Applications implementing their own authentication systems should consider a threshold governor (..) OWASP's ESAPI project contains a reference implementation of a basic threshold governor, which is in turn linked to the intrusion logging mechanism (..)" (bron).
Er is ook een ESAPI voor PHP, en die bevat ook een voorbeeldimplementatie van authentication, maar:
- 1 Mb code vind ik wat veel alleen maar voor beveiliging (ter vergelijking: de open soruce edition van phpPeanuts is rond 1 Mb)
- user data wordt niet in een database opgeslagen maar in via een custom opslagmechanisme op schijf.
- intrusion detection data wordt in $_SESSION opgeslagen.
Ik zou dat toch liever in een database stoppen. Maar ik moet het nog verder bestuderen... Ik ben benieuwd jij (en anderen) hier over te zeggen hebt (hebben).
Sorry, ik zie nu dat 'Tut' het gebruik van Blowfisch al bespreekt. Zij gebruiken de username als salt, en die staat natuurlijk ook gewoon in de database. Dat is makkelijk, maar in 'Topic' wordt juist gesteld dat het een goed idee is om de salt NIET in de database te hebben.
Ik dacht hetzelfde dat het niet verstandig was. Maar het is zo tegenstrijdig. De een stelt zijn prioriteit bij een unieke salt per user en de ander pakt zijn hart vast als die een salt in de database ziet.
Hierom heb ik dit topic gestart.
Henk Verhoeven op 06/12/2012 18:30:39
Wat ik zou doen is zowel een vast salt gebruiken dat in de configuratie van de applicatie moet worden ingesteld, als een variabel salt gebruiken, wat vrees ik toch in de database zal moeten staan. Eventueel eerst het variabele salt hashen samen met het vaste, zodat het voor hackers lastiger is om er achter te komen in welk(e) veld(en) de variabele salt staat (OK, dit is ook obscurity, maar er is toch een flinke kans dat hackers de broncode niet kennen en proberen om het te raden obv de data). En dan de wachtwoord samen het gecombineerde gehashte salt.
Dus wat jij zou doen is beide?
Een deel van de salt in de database en een deel in de broncode?
Henk Verhoeven op 06/12/2012 18:30:39
Maar persoonlijk ben ik er nog niet uit wat nu optimaal is. Wel weet ik dat de OWASP guide aanraadt om een framework te gebruiken en niet je eigen authorization te schrijven (bron. Maar dat is wellicht geen oplossing als je zelf een framework onderhoudt...
Verder mis ik in de meeste tutorials etc. voorzieningen om te proberen om hackpogingen te detecterten:
"Applications implementing their own authentication systems should consider a threshold governor (..) OWASP's ESAPI project contains a reference implementation of a basic threshold governor, which is in turn linked to the intrusion logging mechanism (..)" (bron).
Ja maar een systeem gebruiken haalt de uitdaging eruit. Ik ben met php begonnen als hobbyist, om de door mij gemaakte psd layouts werkelijkheid te maken.
Henk Verhoeven op 06/12/2012 18:30:39
Er is ook een ESAPI voor PHP, en die bevat ook een voorbeeldimplementatie van authentication, maar:
- 1 Mb code vind ik wat veel alleen maar voor beveiliging (ter vergelijking: de open soruce edition van phpPeanuts is rond 1 Mb)
- user data wordt niet in een database opgeslagen maar in via een custom opslagmechanisme op schijf.
- intrusion detection data wordt in $_SESSION opgeslagen.
Ik zou dat toch liever in een database stoppen. Maar ik moet het nog verder bestuderen... Ik ben benieuwd jij (en anderen) hier over te zeggen hebt (hebben).
Zoals je hierboven staat ben ik geen volleerde developer, verre van dat. Ik bezit ook geen extreem gevoelige data, al gebruiken de meeste mensen voor elke site hetzelfde wachtwoord. En de E-mail kunnen ze vinden.
En mede door de vele sites die worden leeg geplukt, laat je zelf naar je eigen code kijken.
Ik probeer zoveel mogelijk te leren en het maximaal veilige te doen. Maar de loginsystemen van hier gebruiken ze een standaard manier van beveiliging sha1/sha256/sha512 enz. en de topics waarin wachtwoordbeveiliging wordt beschreven/uitgelegd komt meer commentaar op dan goede reacties.
Ik wil niet onbeleefd zijn, maar dit is juist wat ik bedoel. Iemand laat een manier van beveiliging zien en 100 man staan klaar met commentaar. "Je kan het beter zo en zo doen.";
Uiteraard van een beheerder van een php hulp site geloof ik wel dat het veilig genoeg is, maar waarom dan het commentaar als het veilig genoeg is?
Zoals die John toen uitlegde als je een veilig wachtwoord hebt kun je hem veilig opslaan ongeacht de beveiliging.
Omdat het ging over de salt, benadrukte ik dat er ook een oplossing is waar je geen salt bij hoeft te gebruiken. Ging over de discussie wel, niet of gedeeltelijk opslaan van de salt.
Oh lol, inderdaad. Niks gezegd! Overigens kan deze wel leegblijven, door de iteraties blijft het vrijwel onmogelijk te kraken (bruteforcen). Het zijn geen standaard hashes.
Toegegeven, men kan hier een database van aanleggen met verschillend aantal iteraties. Dit neemt alleen veel tijd in beslag (bij 20.000 iteraties duurt het gemiddeld 0.05 seconden, dus voor 20.000 iteraties +/- 1000 seconden), en gebaseerd op a-zA-Z0-9 (61 karakters) en schrijven tot 15 karakters, ben je hier wel een aantal jaar zoet mee.