Dynamische salt

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Peter van den Dungen

Peter van den Dungen

10/01/2012 20:43:08
Quote Anchor link
Ik zie regelmatig vragen staan over het gebruik van een salt.Een sluitend antwoord heb ik alleen nog niet kunnen vinden. Dat een salt slechts een klein onderdeel van een goede beveiliging is, (zoals te lezen is in een ander topic) ben ik het helemaal mee eens.

Maar met name bij een dynamische salt vraag ik me wel af wat de beste methode is en wat de nut van deze salt is. In mijn registratie-script maak ik een random salt aan en sla deze (zonder hash) op in de database, los van het wachtwoord (met hash).

Bij het inloggen zal ik de salt op moeten zoeken aan de hand van de inloggegevens van de gebruiker. Dit wordt alleen lastig omdat dat alleen kan met de gebruikersnaam, als deze uniek is.

<code>
$query_salt = mysql_query("
SELECT
salt_wachtwoord
FROM
users
WHERE
gebruikersnaam = '". $login_user ."'
",$connection);


$result_query_salt = mysql_fetch_array($query_salt);
$salt = $result_query_salt['salt_wachtwoord'];
$hashed_wachtwoord = sha1(trim($login_pass . $salt));


$query_checklogin = mysql_query("
SELECT
klantnummer,
gebruikersnaam
FROM
users
WHERE
gebruikersnaam = '". $login_user ."'
AND
hashed_wachtwoord = '". $hashed_wachtwoord ."'
",$connection);
</code>

(foutafhandeling / sql-injection weggelaten in dit voorbeeld)

Op het moment dat de gebruikersnaam niet uniek is werkt dit al niet meer.
Kan iemand vertellen of hier een betere manier voor is? En is het opslaan van een statische salt in de database niet net zo (on)veilig?
Gewijzigd op 10/01/2012 20:56:04 door Peter van den Dungen
 
PHP hulp

PHP hulp

08/05/2024 07:41:50
 
Obelix Idefix

Obelix Idefix

10/01/2012 20:46:47
Quote Anchor link
Peter van den Dungen op 10/01/2012 20:43:08:
Dit wordt alleen lastig omdat dat alleen kan met de gebruikersnaam, als deze uniek is.

Moet er niet aan denken dat twee (of meer) personen dezelfde gebruikersnaam hebben. De kans is klein, maar ze zullen ook met hetzelfde wachtwoord hebben..... Dat risico moet je niet willen lopen.
En daarmee los je ook gelijk jouw probleem op: een unieke gebruikersnaam kun je een dynamische salt aan koppelen.
Gewijzigd op 10/01/2012 20:47:41 door Obelix Idefix
 
Peter van den Dungen

Peter van den Dungen

10/01/2012 20:49:25
Quote Anchor link
Hetzelfde wachtwoord is m.b.v. een dynamische salt geen optie lijkt me.
Is bovenstaand dus toch wel een goede optie met gebruik van een unieke gebruikersnaam?
Gewijzigd op 10/01/2012 20:50:27 door Peter van den Dungen
 
- Jim  -

- Jim -

10/01/2012 20:52:25
Quote Anchor link
Een salt wordt in de database opgeslagen om het gecodeerde wachtwoord beter te beveiligen. (IMHO)

Het antwoord op je vraag is denk ik relatief simpel: 'Dwing unieke gebruikersnamen af!'.
Het is erg ongewenst om 'niet unieke' gebruikersnamen toe te staan. Jan != jan != jAn != jAN.
Het is ook gebruikerlijk om een username in kleine letters te gebruiken. Met de functie toLower() kun je de gebruikernamen naar LowerCase omzetten. Als je toLower() ook gebruikt voor je logins heb je ook geen probleem als je eens met een hoofdletter aanmeldt.
 
Wouter J

Wouter J

10/01/2012 22:07:48
Quote Anchor link
@jim, toLower() is JavaScript in PHP gebruik je strtolower
 
Jeroen VD

Jeroen VD

10/01/2012 22:52:59
Quote Anchor link
Maar wanneer een hacker toegang heeft weten te krijgen tot de database, en hij ziet de salt als plain text staan, kan hij deze toch gewoon verwerken in zijn brute-force, en is het hele nut van een salt toch weg? Kun je de salt dan ook niet veilig opslaan?
 
Dos Moonen

Dos Moonen

11/01/2012 02:11:35
Quote Anchor link
@jeroen, het nut van een salt is het geval van rainbowtables te verminderen. Als je ooit eens database vol hashes gaat bruteforcen voorkomt een salt hopelijk dat hij/zij geen bestaande rainbow table kan gebruiken. Een unieke salt per user voorkomt dat hij/zij één rainbow table voor de hele database aan kan maken terwijl hij hash #1 aan het brute forcen is omdat die rainbow table dan alleen voor die ene salt is. En die is nou net (zo goed als?) uniek per user waarmee de rainbow table dat dus ook wordt.

Ik stel voor dat je zowel een statische als dynamische salt gebruikt. De dynamische sla je op in de database bij de user, misschien zelfs voor/achter de hash. De statische sla je op in de source of een plek waar je met database toegang niet kunt komen maar met php wel.
Ik raad aan dat je een brcypt(hash_hmac(pass, statisch), dynamisch) hashing formaat gebruikt. Zie de crypt() functie voor bcrypt (gebruikt blowfish) of google naar bcrypt!
Gewijzigd op 12/01/2012 00:17:57 door Dos Moonen
 
Obelix Idefix

Obelix Idefix

11/01/2012 07:26:23
Quote Anchor link
Peter van den Dungen op 10/01/2012 20:49:25:
Hetzelfde wachtwoord is m.b.v. een dynamische salt geen optie lijkt me.


Als jij toestaat dat er meerdere keren een gebruikersnaam Jan is, hoe kun je dan de inloggegevens controleren? Welke dynamische salt moet er dan gebruikt worden? Of ga je de hele database door en probeer je elke combinatie van Jan met de bijbehorende dynamische salt?
De meest eenvoudige/praktische oplossing is: gebruikersnaam = uniek.
 
Ozzie PHP

Ozzie PHP

11/01/2012 08:19:58
Quote Anchor link
Misschien een rare vraag... maar hoe werkt zo'n dynamische salt eigenlijk? Wat moet ik me daar bij voorstellen?
 
Wouter J

Wouter J

11/01/2012 08:43:05
Quote Anchor link
Ozzie, je zou met dynamische salt bijv. uniqid kunnen gebruiken. Of zelf wat in elkaar knutselen doormiddel van hashes en tijd functies.
 
Ozzie PHP

Ozzie PHP

11/01/2012 08:54:09
Quote Anchor link
Wouter, tot zover begrijp ik het... maar wat doe je dan met die unieke salt? Sla je die bij de user op in de database?
Gewijzigd op 11/01/2012 08:55:30 door Ozzie PHP
 
Wouter J

Wouter J

11/01/2012 08:58:52
Quote Anchor link
Ja, dat is een optie. Je slaat die dynamische salt op en het wachtwoord. Vervolgens haal je het wachtwoord uit de db en tegelijkertijd ook de dynamische salt en dan haal je de salt uit de db en dan krijg je het wachtwoord zonder salt.

Een optie die ik eens bedacht heb is om een soort key te maken. Deze key is dynamisch en zit tussen de salt en het wachtwoord. Deze key heeft wel 1 ding altijd gemeen, bijv. eerst 2 letters dan 1 cijfer dan 1 letter en dan weer 2 cijfers. Deze verschillen dus per tijd, maar het heeft dezelfde opbouw. Vervolgens kun je dit eruit halen en hiermee de string breken in 2 stukken: De salt en het wachtwoord. Dit wachtwoord kun je vervolgens in een script gebruiken.
 
Jelle -

Jelle -

11/01/2012 08:59:41
Quote Anchor link
Het is eigenlijk heel simpel, voor simpel md5() bestaan ondertussen steeds groeiende databases dus als jouw tabel met md5() gehashte wachtwoorden op straat komt te liggen, ben je de zak.

Als je dan een stap verder gaat met een salt, voeg je eigenlijk gewoon een string toe die zorgt dus dat die ander tabel niet meer bruikbaar is. Je moet immers dan een nieuwe genereren met de salt erbij. Maar als je die eenmaal gegenereerd hebt dan ben je dus weer de zak.

Met een dynamische salt, die je dus eigenlijk per gebruiker opslaat kun je die rainbow tabel ook PER gebruiker gaan genereren. En dan is de lol er snel af want dat kost nog veel te veel tijd (wordt wel steeds minder met de ontwikkelingen van steeds snellere rekenkracht van computers natuurlijk).

Het is dus eigenlijk gewoon een extra horde voor degene die de wachtwoorden buit wil maken en "hackers" zijn vaak lui. Er is immers ook ergens anders wel wat te vinden wat minder beveiligd is :)
 
Ozzie PHP

Ozzie PHP

11/01/2012 09:29:56
Quote Anchor link
Oké, ik snap het. Maaaar... als die database dan op straat komt te liggen... wordt het dan niet makkelijker aangezien per gebruiker keurig vermeld is wat zijn / haar salt is?
 
Jelle -

Jelle -

11/01/2012 09:38:52
Quote Anchor link
Het punt is dat op dat moment het enige wat je nog kan doen het vertragen van achterhalen van de wachtwoorden is. Als iemand PER salt (ookal weet ie de salt) een rainbow tabel moet gaan aanmaken voor duizenden misschien wel tienduizenden gebruikers dat gewoon een eeuwigheid duurt.

Bij één salt voor iedereen kom je er wel achter wat de salt is en als je die eenmaal hebt hoef je dus maar 2 rainbow tabellen te genereren, eentje om te achterhalen wat de salt is (als die niet al via een andere manier te achterhalen is) en daarna eentje om de tabel met die salt erbij te genereren.

Edit:

Dan zit je trouwens ook nog met, als je één salt gebruikt en ze genereren een tabel om die salt te achterhalen (wat ze misschien nog niet eens weten dat dat zo is) dan is de "beveiliging" daarvan net zo sterk als de kortste wachtwoorden.

En ook de hash methode is gewoon erg belangrijk, md5() is eigenlijk veel te snel. Voor jou maakt 20ms misschien niet zo veel uit, bij het genereren van een tabel kan dat jaren/eeuwen schelen.

En wat je ook zou kunnen doen, is voor de salts een aparte database te maken, met een andere user. Dan hebben ze aan een enkele database niet genoeg, maar hebben ze ze eigenlijk beide nodig.
Gewijzigd op 11/01/2012 09:44:43 door Jelle -
 
Ozzie PHP

Ozzie PHP

11/01/2012 09:53:46
Quote Anchor link
Ah oke... ik snap wat je bedoelt. Het is dus puur een vertragende factor als ik het goed begrijp.

Iemand die handig is en beschikt over de database zou natuurlijk een stukje code maken die per gebruik de unieke salt pakt en dan met die unieke salt gaat ie dan de rainbow table afzoeken op een match, maar inderdaad... het wordt er dan wel al een stuk lastiger op. Maar beter lijkt me dan een combinatie van dynamische salt (opgeslagen bij de user in de database) en een vaststaande pepper die NIET in de databse staat maar in de code. Dit zou dan een string kunnen zijn die je zelf hebt verzonnen, of wellicht een gegenereerde string op basis van de url van de website (of iets dergelijks). Dus bijv. md5('www.mijnsite.nl').

Ander ideetje... zou het een idee zijn om op basis van het e-mailadres een salt te creëren? Dus stel je gooit het e-mailadres door een of andere functie... daar komt dan een stukje code uit die je dan als salt zou kunnen gebruiken. Om dan te gaan bruteforcen zou je moeten weten hoe de functie in elkaar zit, anders gaat het je nooit lukken. Zou dit een idee zijn?

p.s. mooie avatar smur f :)
 
Jelle -

Jelle -

11/01/2012 10:15:52
Quote Anchor link
Je kunt inderdaad heel veel kanten op, een dynamische salt + een statische pepper is sowieso wel een goed idee. En tja, je moet op een of andere manier die dynamische salt maken, je zou hem ook gewoon random kunnen genereren (wel met gegarandeerd rare tekens enzo natuurlijk)

Die avatar had ik gisteren even gemaakt op stage :P
Gewijzigd op 11/01/2012 10:17:38 door Jelle -
 
Ozzie PHP

Ozzie PHP

11/01/2012 10:33:18
Quote Anchor link
Als je de dynamische salt genereert aan de hand van een mailadres dan zou deze in principe altijd uniek moeten zijn.

Het nadeel: als men weet hoe de salt gegenereerd wordt dan kan men alsnog rainbow tables gaan maken.

Het voordeel (denk ik): omdat de salt gegenereerd wordt aan de hand van het mailadres hoef je de salt niet in de db op te slaan.

Is dit een goed idee?
 
Jelle -

Jelle -

11/01/2012 10:51:45
Quote Anchor link
Als ze er achter komen hoe die salts worden gegenereerd zijn ze niet veel verder dan als jij het gewoon in de database zou staan dus het zou in principe toch weer een extra blokkade zijn.
 
Ozzie PHP

Ozzie PHP

11/01/2012 11:12:34
Quote Anchor link
Wat bedoel je precies? Ik snap je zin niet helemaal. Is het wel of niet een goed idee volgens jou?
 
Jelle -

Jelle -

11/01/2012 11:48:42
Quote Anchor link
Inderdaad een beetje vage zin, wat ik bedoel is dat:

Stel je voor dat ze achter de functie komen en ze weten hoe jij de salts genereerd dan zijn ze nog niet veel verder dan als niet zon functie zou gebruiken en ze random genereerd en in de database opslaat.

Ook wel, het is wel een goed idee, maar dan moet je wel garanderen dan je rare tekens zoals ? en ^ etc er in zet. Dus het kan nog wel lastig zijn om die salts te maken maar het is geen slecht idee.
 

Pagina: 1 2 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.