Cookies op Tweakers

Tweakers maakt gebruik van cookies, onder andere om de website te analyseren, het gebruiksgemak te vergroten en advertenties te tonen. Door gebruik te maken van deze website, of door op 'Ga verder' te klikken, geef je toestemming voor het gebruik van cookies. Je kunt ook een cookievrije versie van de website bezoeken met minder functionaliteit. Wil je meer informatie over cookies en hoe ze worden gebruikt, bekijk dan ons cookiebeleid.

Meer informatie

Door , , reacties: 142, views: 31.960 •

LinkedIn heeft aangegeven dat alle wachtwoorden van gebruikers nu zijn voorzien van een 'salt', een methode om gehashte wachtwoorden veiliger op te slaan. De site lijkt daarmee aan te geven dat de wachtwoorden tot nu toe niet gesalt waren.

LinkedIn-logoDinsdagavond gaf LinkedIn aan dat alle wachtwoorden van gebruikers nu van een salt zijn voorzien, meldt persbureau Reuters. De uitgelekte wachtwoorden van LinkedIn-gebruikers waren dat niet. LinkedIn zei aanvankelijk al voor het datalek begonnen te zijn met het salten van wachtwoorden. Of dat echt zo is of dat er nu pas salts zijn toegevoegd aan de gehashte wachtwoorden, is onduidelijk.

Een salt is een extra waarde die aan een wachtwoord wordt toegevoegd voordat het wordt gehasht. Daarmee moet worden voorkomen dat de gehashte wachtwoorden met behulp van rainbow tables kunnen worden gekraakt als ze onverhoopt uitlekken.

Daarnaast heeft LinkedIn aangegeven nog een 'extra beveiligingslaag' te zullen aanbrengen, maar wat de zakelijke sociale-netwerksite daarmee bedoelt, blijft onvermeld.

Reacties (142)

Reactiefilter:-11420141+192+223+32
onder het motto:

beter laat dan nooit?

toch blijf ik het vreemd vinden dat bedrijven van dit formaat, die over zoveel gegevens van leden beschikken, dit niet allang hebben...
Inderdaad. Dit is toch wel "hoe sla ik wachtwoorden op"-101. Je zou haast zeggen dat dit als een soort hobbyprojectje is ontstaan, en er toen het populair is geworden nooit meer iemand naar de veiligheid gekeken heeft.

Ik denk dat het motto trouwens was "als het kalf verdronken is..." :)
Dit soort fouten hoort bij een bedrijf dat sneller gegroeid is dan verstandig - de security (en wellicht support, backoffice, etc) groeit niet snel genoeg mee en zorgt uiteindelijk voor problemen... Je begint klein en je doet maar wat - security is door low profile activiteiten nog niet zo belangrijk.

Tegen de tijd dat security wel belangrijk wordt krab je je achter de oren om te bedenken hoe je die migratie dan gaat doen... Wachtwoorden naar een andere hash omzetten gaat (formeel) niet - want daar heb je de plain text wachtwoorden voor nodig. Pas omzetten als het wachtwoord wordt gewijzigd werkt ook niet - die migratie duurt jaren bij de frequentie waarmee mensen hun wachtwoord wijzigen (ergens tussen 1 keer per jaar en nooit).

Facebook is tegen vergelijkbare issues aangelopen - door snel en slordig progammeerwerk veel fouten in de software...
In principe kan je het wachtwoord al omzetten bij inloggen, dan heb je immers al de ongehashte versie van het wachtwoord. En als het allemaal te langzaam gaat, zou je ook alle ongehashte wachtwoorden laten uitlekken, in de hoop dat mensen dan hun wachtwoord gaan wijzigen...
Ik vind het vreemder dat mensen het woord gesalt al kennen. Ik heb er iig nog nooit van gehoord. (maar ben dan ook geen veiligheidsexpert)
Een salt is een extra 'random' waarde die toegevoegd wordt aan het wachtwoord record en welke uniek is per gebruiker. Daarna wordt de hash van het wachtwoord nogmaals gehasht met toevoeging van de salt waardoor een tweede hash ontstaat. Deze tweede hash wordt opgeslagen in de database.

Dit is vooral om te voorkomen dat uit de collisions mogelijk is om het wachtwoord nog uit de hash te halen.
Maar het salt wordt ook ergens opgeslagen. Het is wel een extra beveiliging, maar in dit geval waren de username's (waarschijnlijk) ook buit gemaakt. Of je er dus zoveel mee opschiet?
De salts codes zelf worden vaak niet in de database opgeslagen, dit is immers zinloos gezien de beoogde impact van een DB hack te verkleinen. Het zijn veel eerder twee variabelen die ergens op een beschermde plek staan (bijv. private variabelen van de login klasse). Het beste is om een salt op verschillende plekken van een wachtwoord te gebruiken en de salt string zo lang mogelijk te maken.
Een salt moet je juist per gebruiker uniek maken (en idd, hoe langer hoe beter). Maar deze kun je prima bij ("naast") de gebruiker in de DB opslaan. Er is niets geheims aan een salt en dus hoeven ze ook niet op een beschermde plek te staan. Als je een salt zoals je aangeeft in een login klasse mikt als "constante" dan geef je dus elke user dezelfde salt en doe je het nut ervan, zo goed als, teniet.
In a typical usage for password authentication, the salt is stored along with the output of the one-way function, sometimes along with the number of iterations to be used in generating the output (for key stretching).
...
The benefit provided by using a salted password is making a lookup table assisted dictionary attack against the stored values impractical, provided the salt is large enough. That is, an attacker would not be able to create a precomputed lookup table (i.e. a rainbow table) of hashed values (password + salt), because it would take too much space. A simple dictionary attack is still very possible, although much slower since it cannot be precomputed.
Door elke salt uniek te maken voor elke gebruiker voorkom je voor elke gebruiker dat er een rainbow table gemaakt kan worden. Als jouw ('enkele') salt bekend is maak ik alsnog "zo" een rainbow table en hoef ik voor alle gebruikers gewoon diezelfde salt te gebruiken.

[Reactie gewijzigd door RobIII op 13 juni 2012 11:41]

Het aantal unieke velden in een database is altijd beperkt (uw salt is dus zo gevonden), en als de DB integriteit is gecomprimiteerd, is de salt zonder twijfel in de handen van een hacker. De scheiding salt code in programmatuur / DB geeft dan een extra security layer. No offence, maar je zou niet echt slim zijn om het te laten (10 minuten werk inclusief een facerol op het toetsenbord). Het is kiezen tussen of 100% zeker zijn dat de codes gekraakt kunnen worden, maar een extra moeilijkheid inbouwen; of een grote kans creëren dat de wachtwoorden totaal niet gekraakt kunnen worden omdat de hacker dikwijls alleen toegang heeft tot de DB. Geen moeilijke keus natuurlijk. Maar beter is allebei gebruiken. Een rainbow table is eenvoudig te vertragen door simpelweg een hash in te voegen met het ID van de gebruiker, dit is immers net zo veilig en vertragend als jullie oplossing van een salt in de DB opslaan. Even afgezien van het feit dat een ID al voor zou kunnen komen in combinatie met een ww in de normal rainbow tables.

[Reactie gewijzigd door lopert op 13 juni 2012 12:46]

@lopert: Hoe wil je honderden miljoenen salts in je programmacode opslaan, liefst nog gekoppeld aan userid? Dat klinkt als een database op zich.

Salten met het userid is geen goed idee. De entropie die je uit een userid haalt is erg klein.

Op zich ben ik het wel met je eens dat het opslaan van de salt enig risico met zich meebrengt. Wat dat betreft lijkt de afweging me de volgende:
1. Gebruik ik een grote salt (50 bits+) en sla ik die op.
of
2. Gebruik ik een kleine salt (~20 bits) die ik weggooi en bereken ik voor elke loginpoging alle mogelijke hashes?

Lijkt me een performance-security-afweging

[Reactie gewijzigd door Bacchus op 13 juni 2012 13:21]

Het idee heeft niets te maken met een unieke code per user, alle hashes krijgen dezelfde toevoeging, het gaat er alleen om dat DB / programma code gescheiden zijn. SQL injections zijn gewoon de orde van de dag, en daartegen werkt een DB opgeslagen salt totaal niet. Uiteraard vertraagt het tegen massaal checken van wachtwoorden vanuit rainbow tables, maar uiteindelijk is dit ook het enige voordeel. Als het erop aankomt is dit niet echt een toekomstgerichte methode van veiligheid waarborgen omdat de oploskracht steeds beter wordt.

De database salt sterkte maakt niet zo veel uit als iedereen hier doet voorkomen, aangezien hij gecompromitteerd gaat worden (ergo met hetzelfde gemak plakt de hacker die code - of het nu een ID is of een enorm lange salt - bij een wachtwoord). Het helpt alleen tegen een zeer minimaal aantal incidentele gelijkenissen. Dit is gewoon te verwaarlozen, zeker als iemand mijn extra layer van security implementeert .m.b.v. een constante salt-toevoeging bij de hash (bijv. na het 3rde karakter en op het einde van het wachtwoord) vanuit de code.

Wat ik dan bijv. nog doe is het wijzigen van de constante salt code om de zoveel tijd (inclusief hashes opnieuw uitrekenen), als er een DB hack is geweest, worden ineens alle hashes waardeloos na deze actie.

Zonder te arrogant proberen te klinken was mijn oplossing bij LinkedIn perfect geweest. Hadden ze jullie oplossing gebruikt (een salt opslaan in de database) dan waren gebruikers nu gedwongen geweest hun wachtwoord te wijzigen (vergeet niet dat veel gebruikers dezelfde wachtwoorden toepassen voor andere grote sites als facebook). De reden hiervoor is gewoon dat de juiste tijd alle wachtwoorden kan oplossen, vooral omdat je jezelf nog steeds afhankelijk maakt van de wachtwoord sterkte van de gebruiker (tenzij er sprake was van een verborgen hash salt die ondertussen veranderd is).

[Reactie gewijzigd door lopert op 13 juni 2012 13:48]

@lopert: Je oplossing werkt niet.
Door een constant salt te gebruiken dwing je een aanvaller enkel om één nieuwe rainbowtable te berekenen voor de hele site. Voor een site van de omvang van LinkedIn is dat zeker de moeite waard en zijn alsnog alle wachtwoorden beschikbaar. Erop vertrouwen dat de broncode geheim blijft (of de database open ligt of niet) is misschien wel de meest klassieke beveiligingsfout die er bestaat.

Je hebt gelijk dat uiteindelijk ook een random salted wachtwoord uiteindelijk gekraakt zal worden maar dat duurt een factor "2^saltlengte" langer dan jouw constante salt.
Beste is gewoon allebei de security measures te gebruiken, dat lijkt mij duidelijk. Omdat beide iets toevoegen in de security. De één zorgt voor verdediging tegen SQL injections en de andere vertraagd het kraken significant.

[Reactie gewijzigd door lopert op 13 juni 2012 13:58]

Dit heeft helemaal niets met injection te maken. Injection vang je af door je invoer correct te coderen en je SQL niet via string-concatenation op te bouwen. Of "salt" jij je andere gebruikersinvoer ook? ;)
Grappig :/ Neem aan dat je weet wat ik bedoel => SQL injections die leiden tot database hacks. Als je graag mensen wilt tegenspreken kun je inderdaad alles letterlijk opnemen.

[Reactie gewijzigd door lopert op 13 juni 2012 14:30]

@lopert: Als alle hashes dezelfde toevoeging krijgen noemt men dat een "pepper". Een unieke toevoeging per hash is een "salt".

Unieke salt + een traag hashing algoritme (zoals bcrypt of scrypt) = zeer veilig. Ik gebruik altijd bcrypt met gewicht 10, wat er voor zorgt dat het ongeveer 500ms duurt om 1 hash te berekenen. Snel genoeg om een gebruiker in te loggen, en traag genoeg om brute force unfeasible te maken (~25.000 jaar om een 7 karakter [a-Z0-9] passwoord te kraken. En omdat bcrypt moeilijk te implementeren is op GPGPU's zitten we ook nog een tijdje veilig.
Zonder te arrogant proberen te klinken was mijn oplossing bij LinkedIn perfect geweest.
Zonder arrogant te willen zijn: je hebt geen idee waar je over praat ;)
Lees dit topic eens door: Password hashing met salt ;)

[Reactie gewijzigd door RobIII op 19 juni 2012 10:56]

Salts zijn met name bedoelt om rainbow tables tegen te gaan. De hoeveelheid entropie is derhalve niet zo boeiend, als het maar niet hetzelfde is dan verandert de checksum al. Het testen van miljarden combinaties of dat dat toevallig het wachtwoord is, is niet zomaar even gedaan. Het opzoeken van de hash waarde in een rainbow table (wat dus gewoon een tabel alla 'geprobeerd wachtwoord', 'hash', je zoekt daarin naar de gevonden hash en pakt 'geprobeerd wachtwoord' van dezelfde regel en voila het wachtwoord (of iig 1 waarmee je d'r in komt - hashes zijn NIET uniek).

En een rainbow table aanleggen met alle mogelijke wachtwoorden i.c.m. alle mogelijke salts doe je ook niet even...

Al gebruik je de gebruikersnaam dus direct - altijd nog vele malen beter dan 1 en dezelfde salt gebruiken.
Dit blijft een eeuwige discussie. RobIII heeft echter helemaal gelijk en je moet salts per gebruiker opslaan. Er is niks geheim aan de salt en het geeft dus ook niet als een hacker deze in hangen krijgt. Het enige doel van een salt is het voorkomen van het gebruik van een rainbow table. Niks meer, niks minder.

Als je extra veiligheid wilt met een geheime key/sleutel (zoals jij denkt te bereiken door een salt los op te slaan van je DB) dan zijn daar veel betere oplossingen voor. Je kan dan bijvoorbeeld veel beter het wachtwoord eerst door middel van een symmetrische encryptie (bijvoorbeeld AES, Blowfish) encrypten en daarvan een hash berekenen (met een salt per gebruiker) en die hash samen met de salt opslaan in de DB. De key van je symmetrische encryptie moet je dan uiteraard wel veilig opslaan. Je hebt dan het beste van twee werelden. En dat is in feite wat bCrypt doet, vandaar dat dit tegenwoordig steeds populairder wordt.
Een salt maakt nog niet heilig, hoor. De toepasbaarheid hang volledig af van het type hash dat je gebruikt. In dit geval wil men dus een password hash algoritme gebruiken, en niet een crypografische hash, want anders kan een aanvallertje alsnog gaan proberen om wachtwoorden te gaan bruteforcen. En alhoewel de moeite maar een enkele gebruiker bloot legt is het nog steeds een zwakheid, want vaak kom je al een heel eind als je alleen maar een admin wachtwoord bloot legt.

Bron linkje: http://krebsonsecurity.co...eef-up-password-security/
Interessant stukje!
Daarom moet je ook zorgen dat je hash algoritme ingewikkelder en CPU intensief genoeg is. LinkedIn gebruikte enkelvoudige SHA1 en dat is een zeer eenvoudige en snel te berekenen hash. Veel beter is het om bijvoorbeeld 512-bits SHA2 te gebruiken en dan bijvoorbeeld een paar duizend keer achter elkaar. Na iedere hash voeg je de salt weer toe en bereken je opnieuw de hash en dat een paar duizend keer achter elkaar.
Salt wordt vaak wel mee opgeslagen in de DB. En inderdaad is het zo minder effectief.

Het vertraagt de hacker wel, daar hij de gehele rainbow table weer moet voorzien van de salt, alvorens hij deze vergelijkt met de hash van de user. (En iedere user heeft zijn eigen salt.)

Beter zou zijn als er 2 salts zouden zijn. Een per user, en een vaste die niet in de DB staat.
Voorop: Ik ben geen security expert.

Als de hacker maar één account wilt hacken en dus naar één wachtwoord op zoek is dan neemt de kans van falen van je maatregelen enorm toe als de hacker de salt kent.
De salt opslaan in de database is dus imho geen goed idee.

Ik gebruik een constante die dus hetzelfde is voor alle users.
Daar voeg ik de string length van het password aan toe als extra salt.
Zo heb ik volgens mij een redelijk resultaat, met de nadruk op redelijk.

Ook is volgens mij een langere salt niet per definitie beter omdat je kans op collision toeneemt. Dit kan ik ook helemaal verkeerd begrepen hebben, het is ook al even geleden dat ik me daarin ingelezen heb.

Edit: het lijkt niet duidelijk dat ik elke stap hash.

[Reactie gewijzigd door Raymond P op 13 juni 2012 13:37]

Er is een verschil in het volgende: Krijgt de hacker dmv account met wachtwoord toegang tot de db of heeft de hacker al toegang tot een db met een account tabel.

Dezelfde salt voor elk account geeft ook risico's als de salt bekend wordt.
@Raymond:
Dit heeft weinig zin: zo hoef je nog steeds maar één rainbowtable voor je applicatie te berekenen. Voor een site als LinkedIn lijkt die investering mij een schijntje.
Ik heb mijn post ietswat duidelijker gemaakt.
Volgens mij heb ik 1 * mogelijke lengte password aan rainbowtables per user mits users unieke wachtwoorden hebben.

@Martao, als ik je salt weet dan kan ik een veel kleinere en efficientere rainbow table maken. Als je een zwak wachtwoord in je database hebt staan, zoals asda, dan is het peanuts om de positie van je salt te bepalen (voor of achter het wachtwoord) en heb ik effectief nog maar 1 table nodig om het wachtwoord te raden.

Let wel: voor mij is het vaker veel interessanter om het wachtwoord van een enkele gebruiker te weten dan iedereen z'n wachtwoord te hebben.
Huh?
Allereerst: het lijkt me duidelijk dat sites goede wachtwoorden moeten eisen en dat je als gebruiker daar ook je best voor moet doen.
Maar daarnaast, hoezo zou het door de salt makkelijker worden? Sorry, dat volg ik niet.
Vrij simpel.
Als bijvoorbeeld je salt 4 chars is en ik weet je salt niet dan is mijn database met hashes groter.
Ik moet dan namelijk vóór en ná elk mogelijk wachtwoord ook nog eens alle mogelijke salts zetten die je kan maken met 4 chars om een complete database met hashes te krijgen.

Als ik je salt wel heb, dan is het aantal hashes dat ik nodig zou moeten hebben effectief minder, want de salt hoeft niet geraden te worden.
Plus zoals hiervoor gemeld zou ik een zwakker wachtwoord kunnen gebruiken om te zien waar je salt staat.
Een zwakker wachtwoord zou bijvoorbeeld ook van mij zelf af kunnen komen.
Nou ja, ik weet er niet genoeg van om je echt tegen te spreken, maar volgens mij klopt er iets niet aan je verhaal.
Zoals ik het begrijp is het gebruik van salts juist om een rainbow attack tegen te gaan. Dwz dus het hebben van een grote lijst met hashes, die je dan kunt gebruiken om er een deel van te ontcijferen. Dit kan niet, of wordt in ieder geval gereduceerd tot een brute-force attack, door goed gebruik van een (of meerdere salt).

Jij beweert dat het hebben van 1 wachtwoord voor jou interessanter is. Als de rainbow attack geblokkeerd wordt, kan dat best zo zijn, lijkt mij.
Maar, het kraken van 1 enkel wachtwoord blijft toch precies hetzelfde met of zonder hash. Dus de vraag blijft dan over of je een goed wachtwoord hebt en een goede hashing methode?
Onzin, volgens mij. De salt kan je gewoon naast de username opslaan. Het punt is alleen dat wachtwoord X bij user Y en user Z niet dezelfde encrypted waarde krijgen. Het maakt daarbij totaal niet uit of de hacker de salt kent.
Voor mijn eigen systeempje gebruik ik per gebruiker een salt die ik in de database opsla, plus een salt die gelijk is voor de gehele website. Die laatste staat echter niet in de database, waardoor die apart gekraakt zou moeten worden. De extra impact van deze constante waarde op de performance is nagenoeg nul en je maakt het de aanvaller vele malen moeilijker. Door de unieke salt per gebruiker zou een rainbow table per gebruiker gemaakt moeten worden, wat dus neerkomt op een brute force attrack.

Overigens plak ik de constante, de salt en het wachtwoord in één keer achter elkaar (niet per se in die volgorde) voordat ik het geheel hash, het lijkt me wat overdreven om alles apart te hashen. De veiligheid vind ik wel voldoende geborgd om te kunnen stellen dat het niet aan de manier van opslag zal liggen.

[Reactie gewijzigd door ari op 13 juni 2012 23:45]

Al weten ze wat de salt is, kunnen ze geen rainbow table attack meer uitvoeren. In ieder geval niet met bestaande rainbow tables.
Het beste zou zijn om voor elke gebruiker een andere salt te gebruiken. Bijvoorbeeld de username. Dan zou je voor elke gebruiker een nieuwe rainbowtable moeten maken, waardoor zelfs een bruteforce aanval makkelijker zou zijn.

Als je geen salt gebruikt, kun je 1 (bestaande) rainbow table gebruiken voor alle wachtwoorden.
Als er bij alle gebruikers dezelfde salt wordt gebruikt, moet er een nieuwe rainbow table worden gemaakt (als je de salt eenmaal weet)
Tja, dat is wat ik normaal gesproken doe en imo de enige juist manier, bijvoorbeeld:

[code] hashAES256(username + password + email + dateofbirth + "FH*$&GHV23FUDG")l[/code]

Knappe jongen die dat met een rainbow table wil gaan aanvallen en het wachtwoord raad :)
En nu dat iteratief herhalen, iedere keer weer (username + email + dateofbirth + "FH*$&GHV23FUDG) aan het resultaat toevoegend, gedurende een paar duizend runs en je hebt 't echt veilig opgeslagen.

Die paar duizend iteraties maken geen zak uit voor een legitieme gebruiker die inlogt, maar voor de cracker die een brute force aanval doet vertraagt het het proces aanzienlijk. Bovendien kun je dan helemaal wel opdoeken met je rainbow tables.
Enige juiste manier is ***
Maar je dwingt jezelf er nu wel toe om elke keer wanneer iemand iets in zijn profiel wijzigt de wachtwoordhash opnieuw te berekenen.

Bij veel van dit soort methodes vraag ik me af of het geen overkill is voor de gewenste veiligheid.
Bij alleen een database dump zal een hash niet snel gevonden worden zolang de hacker niet over het format beschikt.
Wanneer iemand toegang zou hebben tot de code is dit nauwelijks veiliger dan een hash gemaakt met maar 1 uniek salt per account.

Het is een leuk om het zo complex mogelijk te maken, maar ik vind het verspilde moeite. Ik denk dat een unieke salt per gebruiker en een hardcoded salt al meer dan voldoende zijn.
Dus als ik het in want minder technische woorden omschrijf is het?

Ik geef op wachtwoord: tweakers123 op.
Dan maakt salt er van ietsblablabla345-tweakers123

En als je dat dan hasht krijg je 32, 128 random tekens.

Klopt dit?
Eerder:
Wachtwoord: tweakers123
Hash wachtwoord: 5498f87da579d83e021a0dc7303a6121ae228478
Salt toevoegen: ietsblablabla345-5498f87da579d83e021a0dc7303a6121ae228478
Uiteindelijke hash: b6ee19adaa1344b5564043d3918e3b2fdb60a9d9

Iemand met hetzelfde tweakers123 wachtwoord zal een andere salt hebben waardoor de uiteindelijke hash alsnog anders is. Als de hackers dus 1 wachtwoord zouden kraken en nog 100 users hebben datzelfde wachtwoord dan zal de hacker dat pas weten als hij ze allemaal gekraakt heeft, wat een pak langer zal duren dan zonder salt, als het al lukt.

[Reactie gewijzigd door MClaeys op 13 juni 2012 11:43]

Jouw salt valt wel erg op. Als ik uit een rainbow table, of met een brute force, van de hash "b6ee19adaa1344b5564043d3918e3b2fdb60a9d9" naar de invoer "ietsblablabla345-5498f87da579d83e021a0dc7303a6121ae228478" ga, herken ik onmiddelijk de salt en het wachtwoord, je scheidt het zelfs netjes met een -. Daarna kan ik het achterste deel "5498f87da579d83e021a0dc7303a6121ae228478" weer in een rainbow table doen of opnieuw brute forcen.

Het enige voordeel wat jouw oplossing geeft is dat het wachtwoord langer wordt, maar niet dat het niet te achterhalen valt.

Een betere oplossing is om de salt te verwerken met het originele, plaintext, wachtwoord. Als je bv. de username pakt en die (gedeeltelijk) in het plaintext wachtwoord verwerkt, kun je niet zien of die user (een deel van) zijn username als ww gebruikt, of dat het de salt is.
Klopt, dat was omdat ik zijn eigen voorbeeld even nam om het duidelijker te maken. Ze scheiden met een streepje is inderdaad niet slim en ik veronderstel dat LinkedIn dat dan ook niet zal doen ;). Komt nog eens bij dat zelfs met dit voorbeeld het al niet simpel zal zijn om naar de eerste hash te gaan. Als het al mogelijk is.

[Reactie gewijzigd door MClaeys op 13 juni 2012 14:23]

Zo'n opvallende salt is geen risico. Zowel een rainbow table attack als een brute force attack zullen namelijk niet alle mogelijke hashes gaan proberen, maar alle mogelijke inputs, voor zover die het kraken waard zijn althans. Dat loont omdat het wachtwoord doorgaans veel minder lang is dan een hash van 128 bits (md5 als voorbeeld).

Ga je zo'n hash echter opnieuw hashen en probeer je die laatste operatie ongedaan te maken, dan kun je aannemen dat de invoer sowieso 128 bits lang is geweest. Die operatie is in theorie nog net reversibel mits alle inputs een unieke hash opleveren. Met wachtwoorden van acht tekens is dat nog zeer waarschijnlijk, met inputs van 128 bits zeker niet. Vergelijk het met de kans dat in een willekeurige groep van 356 mensen, iedereen een andere verjaardag heeft. Die kans is ongeveer één op 10^135. Extrapoleer dat nu naar driehonderd sextiljoen mensen en evenveel data.

Volgens de pricewatch ben je vandaag de dag zo'n vierhonderd triljoen keer het wereldwijd GDP kwijt aan hardeschijfruimte om daar een rainbow table voor op te slaan.

Voeg je een salt toe aan de input, in jouw voorbeeld 'ietsblablabla345', dan wordt de kans op het ontbreken van collisions geheel nul, vanwege het pigeonhole principle. Collisions zullen zo frequent zijn, dat de kans dat je überhaupt de 'juiste' input te pakken hebt na een hit in je brute force attack, in de ordegrootte 10^-39 ligt. Die opvallende salt, nota bene met een streepje gescheiden van de rest van de input, zul je dus niet te zien krijgen. Je krijgt een andere zooi pseudowillekeurige tekens die uiteindelijk dezelfde hash oplevert.

Let wel, als je je hier allemaal doorheen hebt geslagen, heb je nog het wachtwoord niet. Je hebt het probleem slechts gereduceerd tot een ongezouten hash van het wachtwoord.

De aanvalsroute die jij voorstelt is niet reëel. Men zal niet pogen de tweede hashfunctie los te breken, tenzij er methoden gevonden worden om de input space sterk te verkleinen door het algoritme direct om te keren. In plaats daarvan zal men direct bij het wachtwoord beginnen en vervolgens bij elke poging alle stappen van het proces voorwaarts doorlopen. Als de aanvaller beschikt over de wachtwoordendatabase om tegen te checken, dan kun zeker veronderstellen dat de salts ook gewoon bekend zijn.
@highmastdon hoe en waar wordt deze salt dan opgeslagen? De salt is nodig om het wachtwoord te valideren als men wederom inlogt toch?

Met andere woorden, als ik de salt weet, kan ik dan alsnog gebruik maken van rainbow tables?
Nee, als het goed geimplementeerd is, is de salt voor elke gebruiker anders. Er zou dan per gebruiker een rainbow table aangemaakt moeten worden wat in feite neerkomt op het "gewoon" moeten bruteforcen van elk wachtwoord. Het kan dus nog wel gekraakt worden maar dit is dan verre van rendabel.

Een andere maatregel die vaak (in combinatie met een salt) toegepast wordt is het herhaaldelijk hashen van een wachtwoord. De gebruikte hashmethode wordt dan bijvoorbeeld 5000 keer achter elkaar uitgevoerd voordat de hash opgeslagen wordt. Om het wachtwoord te kraken zal dezelfde, veel tragere, procedure gevolgd moeten worden wat het bruteforcen vanuit een praktisch oogpunt onmogelijk maakt.

Uiteraard staat of valt alles met de complexiteit van het wachtwoord van de gebruiker en het gedrag van de gebruiker zelf.
Een andere maatregel die vaak (in combinatie met een salt) toegepast wordt is het herhaaldelijk hashen van een wachtwoord. De gebruikte hashmethode wordt dan bijvoorbeeld 5000 keer achter elkaar uitgevoerd voordat de hash opgeslagen wordt. Om het wachtwoord te kraken zal dezelfde, veel tragere, procedure gevolgd moeten worden wat het bruteforcen vanuit een praktisch oogpunt onmogelijk maakt.
:Y Dat heet Key stretching
als een goede salt wordt toegepast, en de hash wordt 5000x herhaald
(en misschien ook de salt meerdere keren toegepast) eventueel in combinatie met het ergens hier bovengenoemde gebruik van een 'onbekende' salt die niet in de database staat, in hoeverre is de complexiteit van mijn wachtwoord dan nog van invloed?

De attacker weet immers niet hoevaak de hash herhaald moet worden (5000x, 2000x, 10000x ?) ze weten niet of de salt meerdere keren herhaald toegevoegd is, ze kennen de 'onbekende' salt niet.

Als iedere site dit goed toepast, is het dan niet veilig genoeg dat ik overal met dezelfde 4 cijfers pincode inlog ?

Aangezien voor elke site de salt, het aantal hash herhalingen en de onbekende salt anders zullen zijn
Die is niet van invloed op de brute-force aanval op je hash, maar wel op je account zelf (mits dat niet beveiligd is).
Nee, de 'workfactor' (5000x, 2000x, wat dan ook) moet ook ergens opgeslagen worden, bijv. in de config van je webapplicatie, aangezien het password hash algoritme deze weer nodig heeft wanneer je wilt inloggen. Het algoritme moet dan immers net zoveel hashing-iteraties doen dan bij het aanmaken van de hash is gedaan, zodat het eindresultaat vergeleken kan worden met de opgeslagen waarde.

Het is niet erg als de aanvaller deze workfactor achterhaalt. Deze is puur bedoeld om het genereren van hashes kostbaar te maken. Door bijv. te zorgen dat elke password hash 100 milliseconden kost, kan de aanvaller er nog maar 10 per seconde maken, en is het bouwen van een gepaste rainbow-table ondoenlijk geworden. Deze vertraging geldt ook voor de applicatiebouwer, omdat bijv. het inloggen met 100 milliseconden vertraagd wordt, maar dat valt in het niet bij de miljarden hashes die een brute-force aanvaller moet berekenen.

Naarmate de beschikbare hardware in de toekomst sneller wordt kan de workfactor verder verhoogd worden (bijv. van 5.000 naar 10.000). De al opgeslagen hashes worden dan simpelweg nog 5000x extra geïtereerd en zijn weer veilig tegen een brute-force aanval.
Maar alsnog moet de salt ergens opgeslagen worden toch? Of wordt deze slechts eenmalig gegeneerd bij het opslaan van je password en dan weggegooid? Het lijkt me toch dat de salt dan per gebruiker moet worden opgeslagen, anders kan nooit als men weer inlogt het wachtwoord op correctheid worden gecheckt?
Je zal een salt altijd moeten weten anders kan je de hash niet opnieuw berekenen en kan de gebruiker niet meer inloggen. Maar door van de salt samen te stellen met het jaar van zijn geboorte, eerste 5 tekens van zijn e-mail adres en zijn voornaam als deze begint met a-k heb je wel een hele lastige salt. Zeker als je deze allemaal nog seperaat hashed, bijvoorbeed:

hash(email+hash(^&%$^6723GFg+hash(yearofbirth+(hash(username+(hash+(wachtwoord)))))
De salt word gewoon als extra kolom in de database opgeslagen samen met het wachtwoord. De salt hoeft niet geheim te blijven, het punt is namelijk dat een aanvaller nu voor elke gebruiker een aparte set rainbow tables moet bouwen. En dat kost heel veel tijd, wat een dergelijke aanval onaantrekkelijk/onmogelijk maakt.
Nee, het maakt eigenlijk niet zoveel uit als het salt bekend is. Rainbowtables staan vol met veelvoorkomende hashes. Door het toegevoegde salt zullen de hashes niet meer veelvoorkomend zijn.

wachtwoord: asdfg
hashen --> SHA1(asdfg) geeft de hash:
f1b699cc9af3eeb98e5de244ca7802ae38e77bae

Omdat veel mensen het wachtwoord asdfg hebben zal deze hash voorkomen in rainbowtables. Nu hashen we deze hash nogmaals met het salt "zoutpotje".

SHA1(f1b699cc9af3eeb98e5de244ca7802ae38e77baezoutpotje) geeft de hash:
d9b387a34bbebbe3e05bda2476788b6c5b061909

Deze hash is uniek en zal niet voorkomen in rainbowtables. (tenzij veel sites het salt 'zoutpotje' gebruiken en dan ook nog op dezelfde manier)

[Reactie gewijzigd door Ras op 13 juni 2012 11:39]

Precies, dat betekend dat een aanvaller een custom rainbow-table moet bouwen voor élke gebruikte salt-waarde. Dat kost enorm veel tijd.

Het systeem is nog veel veiliger te maken door het aantal hash-iteraties te verhogen zodat de kosten van het berekenen van een hash flink toenemen. Een cryptografish hash-algoritme is gemaakt om zeer snel te zijn, terwijl je bij wachtwoorden juist bewust een vertraging wilt inbouwen. Gebruik daarom een password-hash, zoals bcrypt, die een 'workfactor' toevoegd aan de hash. Deze workfactor maakt het berekenen van een hash traag en daardoor kostbaar voor een aanvaller. De workfactor kan verhoogd worden naar mate hardware sneller wordt, om de technologie voor te blijven.

Lees bijv.: http://krebsonsecurity.co...eef-up-password-security/
Je hoeft geen veiligheidsexpert te zijn om er al van gehoord te hebben.

ASP.Net websites in Visual Studio 2005 met voorgekauwde login functionaliteit maakten al gebruikt van salts. Microsoft gebruikte deze feature expliciet in hun 'promo-praatjes' rond Visual Studio 2005. Ik denk dat dit toch wel een grote bijdrage tot de bekendheid van salts heeft gegeven (toch in de Microsoft wereld).

Let wel, Microsoft reageerde ook maar op een trent die al een aantal jaar zichtbaar was bij de betere web-ontwikkelaars. Salten is dus iets wat zeker al 10 jaar common practice is.

Ik vermoed dan ook dat de login-functionaliteit van LinkedIn een grote hap legacy code is waar al in geen jaren naar gekeken is. Wellicht onder het motto van "if it ain't broken...". En daar hebben ze nu de prijs voor betaald.
Dude, de Unix passwd file maakte al gebruik van salts. Zolang ik me kan herinneren. En dat betekent jaren tachtig. Waarschijnlijk zaten die salts er al vanaf het begin in. Dus 1970. En het zou me niks verbazen als het idee van salts al ouder dan 1970 is.

http://en.wikipedia.org/wiki/Salt_%28cryptography%29

[Reactie gewijzigd door gryz op 13 juni 2012 11:58]

Als een site het missen van een Salt niet als aanvalsvector ziet (onder het motto: het is toch zo ook al gehashed?) dan kan ik best begrijpen dat er niets mee gebeurt. Vergeet niet dat niet iedere Security Officier volledig op de hoogte is van de stand van zaken mbt mogelijke collisions in hashalgoritmes. Dus iets wat vandaag nog goed is (vb: SHA1) kan morgen al compleet onveilig blijken. En wil je het als SO goed doen en je krijgt de overstap naar SHA512 niet intern verkocht omdat je leidinggevende er geen nut in ziet (het werkt zo toch ook? laat dan eens een collision zien? oh die is er nog niet, waarom wil je het dan aanpassen?) dan sta je ook met lege handen.

[Reactie gewijzigd door Rick2910 op 13 juni 2012 10:47]

Als er niet naar je geluisterd word is het meestal tijd om je heil ergens anders te zoeken. Zeker als Security Officier die blijkbaar niet empowered is.

Picant detail in dit alles: elke java libary die ik ken (sun/bouncycasle/apache) die SHA1 kan kan ook ook SHA512. Als je het standaard framework(en zo niet vaak ook) is het een kwestie van een string aanpassen. Dus de inspanning voor implementatie is minimaal dan is er alleen nog het verhaal van deployen en migreren maar dit zijn stappen die men ook moet uitvoeren om salt toe te voegen. :Y)
Als een site het missen van een Salt niet als aanvalsvector ziet (onder het motto: het is toch zo ook al gehashed?) dan kan ik best begrijpen dat er niets mee gebeurt. Vergeet niet dat niet iedere Security Officier volledig op de hoogte is van de stand van zaken mbt mogelijke collisions in hashalgoritmes
Sorry maar dat gaat in dit geval echt nergens over. Het gebruiken van een salt is gewoon security 101, en kwetsbaarheden met collisions hebben daar niets mee te maken. Ongeacht het gebruikte hash algoritme, je wil niet dat de hash van Pietje en Henkie hetzelfde zijn als ze toevallig hetzelfde wachtwoord gebruiken. En in het verlengde daarvan, je wil ook niet dat een aanvaller die beschikt over een database van hashes met een dictionary attack of simpelweg brute force in een keer de hele database kan checken ipv dat hij dat per persoon moet doen (in het geval van LinkedIn met 161 miljoen gebruikers vergroot het niet gebruiken van een salt de kans dus met 161 miljoen dat een attacker een wachtwoord van een gebruiker achterhaalt).
Dus iets wat vandaag nog goed is (vb: SHA1) kan morgen al compleet onveilig blijken.
Klopt, met twee kanttekeningen: ten eerste was SHA-1 gisteren al niet goed meer, en ten tweede is SHA-512 net zo slecht. Het gaat namelijk niet echt om het aantal bits in de hash. Zelfs MD5 is wat dat betreft gewoon afdoende - al zou je een biljard hashes per seconde kunnen berekenen, dan nog ben je gemiddeld 1016 jaar bezig om een collision te vinden.

Het specifieke probleem van wachtwoorden is dat de input space (het aantal mogelijke wachtwoorden) veel kleiner is dan de output space (het aantal mogelijke hashes), dat is zelfs bij een relatief kleine 128 bits hash zoals MD5 nog het geval. Als je uitgaat van wachtwoorden van louter alphanumerieke tekens van maximaal 10 tekens lang (dit zijn de meest voorkomende wachtwoorden), dan zijn er maar 6210 =~ 1017 verschillende wachtwoorden mogelijk. En dat terwijl er 2128 =~ 1038 verschillende hashes bestaan. De kans op collision is dus sowieso erg klein.

Een hash algoritme met als doel wachtwoorden te hashen is natuurlijk pas echt compromized op het moment dat een pre-image attack mogelijk is. Oftewel, als door te kijken naar de bits van de hash een sterk gereduceerde set van mogelijke inputs te genereren is, waarna je die kunt proberen. Maar ondanks het feit dat MD5 inmiddels een hoop flaws kent is dit er niet een van, en die bekende flaws zijn voor het doel van het hashen van wachtwoorden eigenlijk compleet oninteressant.

De reden waarom MD5 en SHA (welke variant dan ook) niet voldoen is omdat ze veel te snel te berekenen zijn. Als je wachtwoorden wilt hashen, kun je beter kijken naar algoritmes die aan key stretching doen, zoals PBKDF2 (ook gebruikt op tweakers.net) of bcrypt. Het mooie daarvan is dat ze kunnen meegroeien met de hardware - als de hardware in de loop der tijd steeds sneller en sneller wordt dan vergroot je gewoon het aantal iteraties in het algoritme.
En wil je het als SO goed doen en je krijgt de overstap naar SHA512 niet intern verkocht omdat je leidinggevende er geen nut in ziet (het werkt zo toch ook? laat dan eens een collision zien?
Als een SO het op die manier probeert te verkopen dan heeft ie niet echt verstand van z'n vak ;)

[Reactie gewijzigd door .oisyn op 13 juni 2012 12:19]

ten eerste was SHA-1 gisteren al niet goed meer
Dat is op dit moment nog puur theoretisch (er is nog geen efficiënte collision exploit voor) maar algemeen wordt idd afgeraden om het nog te gebruiken voor kritische zaken als passwords.
Ongeacht het gebruikte hash algoritme, je wil niet dat de hash van Pietje en Henkie hetzelfde zijn als ze toevallig hetzelfde wachtwoord gebruiken.
Hoe randomiseer je de salt dan in dat geval? Want je zult bij het comparen die string toch weer ergens vandaan moeten halen (ervan uitgaande dat je geen sitewide static salt gebruikt maar een die per username identiek is).
Edit: Zelfs zoiets: SHA512((SHA512(emailaddress+staticsalt) + SHA512(password)) is niet veilig indien ze de salt weten te stelen. Of is daar een passend antwoord voor in de vorm van een andere methodiek?
Als een SO het op die manier probeert te verkopen dan heeft ie niet echt verstand van z'n vak
Degene die het geld beheert is vaak niet degene die er technisch volledig in zit. Het laatste wat zo iemand wil is budget vrijmaken voor iets waar geen 'real-world' risico's aan vast zitten (hoewel dat in dit geval natuurlijk discutabel is). En nog veel erger (heb ik al meerdere keren meegemaakt) is dat een SO gewoon te horen krijgt dat er helemaal geen budget meer is en dat het zo lang mogelijk (lees: tot er weer budget is) onder de pet moet worden gehouden. Daarom kunnen/konden LulzSec en Anonymous ook zoveel sites aanvallen: veel sites waar ze op schoten houden er zo'n gedachte op na, dus dan vind je vrij snel doelwitten.

[Reactie gewijzigd door Rick2910 op 13 juni 2012 12:11]

Dat is op dit moment nog puur theoretisch (er is nog geen efficiënte collision exploit voor)
Dat geldt voor MD5 ook. De enige exploits die MD5 kent zijn weak en strong collision attacks, beide geheel irrelevant voor het hashen van wachtwoorden. Het is helemaal niet interessant dat je het originele wachtwoord zo kunt manipuleren zodat de hash hetzelfde blijft (strong collision attack) of dat je twee verschillende wachtwoorden kunt bedenken die dezelfde hash opleveren (weak collision attack). Wat van belang is is dat je niet makkelijk een input kunt vinden die een specifieke hash oplevert (pre-image attack)
Hoe randomiseer je de salt dan in dat geval? Want je zult bij het comparen die string toch weer ergens vandaan moeten halen (ervan uitgaande dat je geen sitewide static salt gebruikt maar een die per username identiek is).
Die sla je gewoon op bij de hash. Dat kan gewoon een random string zijn, of iets wat je al bij de gebruiker kunt vinden (zoals het e-mail adres) zolang er maar genoeg entropie in zit. (Het nadeel van het gebruik van andere gegevens zoals e-mailadres is dat dat soort gegevens meestal te wijzigen zijn, en je dan niet opnieuw de hash kunt uitrekenen aan de hand van de veranderde gegevens zonder het oorspronkelijke wachtwoord te kennen - een extra database-veld voor de salt is dan een stuk praktischer)

En over het SO-verhaal, ik had het op de manier die jij omschreef, dus met het opzoeken van collisions. Dat zijn gewoon geen valide argumenten. Hij moet het proberen te verkopen met sterke argumenten en risico analyse, zoals ik enigszins gaf in mijn post. Wellicht dat zijn meerdere dan alsnog niet overstag gaat, maar dan heeft hij in ieder geval zijn werk goed gedaan. ;)

[Reactie gewijzigd door .oisyn op 13 juni 2012 12:52]

Zelfs MD5 is wat dat betreft gewoon afdoende - al zou je een biljard hashes per seconde kunnen berekenen, dan nog ben je gemiddeld 1016 jaar bezig om een collision te vinden.
MD5 is al lang niet meer goed, daar zijn al collisions voor te vinden.
Om een collision te vinden als er een salt is, dan is die salt gewoon de pre-image.
Anders dan bij certificaten en handtekeningen is het voor wachtwoorden compleet oninteressant om collision te kunnen creëren. Waar het om gaat is dat de originele input terug te halen is (oftewel een pre-image attack), en dat kan met MD5 niet zonder simpelweg te brute-forcen. En het gebruik van een salt staat hier verder volledig los van.

[Reactie gewijzigd door .oisyn op 13 juni 2012 12:21]

Maar als jij met password P en salt S de hash H krijgt en ik kan een collision vinden die met password P' en salt S ook hash H geeft kan ik toch inloggen op jou naam met password P' of zie ik dan wat fout?
Een aantal dingen:

• We hebben het dan over een pre-image attack. Dat is voor MD5 (nog) niet mogelijk voor zo ver ik weet. [.edit: wikipedia is het met mij eens:
All currently known practical or almost-practical attacks on MD5 and SHA-1 are collision attacks [dus geen pre-image attacks].
]

• De kans dat P <> P' is nogal klein aangezien er veel minder verschillende wachtwoorden dan verschillende hashes zijn (tenzij je het hebt over wachtwoorden van 20+ tekens). Als jij een collision vindt met mijn hash dan is de kans groot dat dat mijn oorspronkelijke wachtwoord was.

• In het geval dat P <> P', het feit dat jij kan inloggen op mijn account lijkt me niet zo heel erg boeiend als het je al gelukt is de hashes uit de database te bemachtigen, dan is de server compromized en ben je typisch tot veel meer in staat en heb je mijn ww niet meer nodig om in te kunnen loggen. En inloggen op een andere site onder mijn naam lukt je niet wegens (hopelijk) een andere salt.

[Reactie gewijzigd door .oisyn op 13 juni 2012 12:39]

http://www.win.tue.nl/hashclash/
Chosen-prefix is toch pre-image?

This means that for any targeted pair of distinct messages m1 and m2 we can effectively construct appendages b1 and b2 such that MD5(m1||b1) equals MD5(m2||b2).
Dat klinkt wel alsof het kan wat ik zeg. Alleen moet je dan voor een password waarschijnlijk nog iets moeten dan dat je geen binairy krijgt, dat tikt wat lastig.
"Pre-image" slaat op de input. De image zelf is de hash. Vandaar een pre-image attack - het achterhalen van de input bij een hash. Heeft dus niets met prefixing te maken.

Jij hebt het over een weak collision attack (ookwel secondary pre-image attack). Heb je niets aan, het enige dat je bij een wachtwoord hebt is MD5(m||salt), zonder dat je m weet. En het punt is juist het achterhalen van m.

[Reactie gewijzigd door .oisyn op 13 juni 2012 16:59]

Het is niet zozeer dat een bepaald hash algoritme onveilig is door collisions, een gehashed wachtwoord zonder salt is heel eenvoudig op te zoeken via een rainbow table.

Een rainbow table is een database met daarin miljoenen strings met bijbehorende hashes, het is dus een kwestie van zoeken met de hash en je krijgt de bijbehorende oorspronkelijke string terug. Wanneer je wachtwoord hashed met een salt dan is het alweer een stuk moeilijker om deze via een rainbow table op te zoeken (de hash van "password123" is makkelijker te herleiden dan de hash van "Ak#1" + "password123").

Ongeacht het gebruikte hash algoritme is dit mogelijk (hoewel een methode als bcrypt dit alweer een stuk lastiger maakt) en moet je eigenlijk gewoon een salt gebruiken. Dat heeft niets meer te maken met 'op de hoogte zijn van de stand van zaken', het principe van een rainbow table is zo eenvoudig en oud dat je het wel zou moeten kennen als je ook maar iets met webdevelopment te maken hebt.
Het probleem is (en dat stipt .oisyn ook al even aan) dat een static salt allen wat langer duurt om te decrypten. Meestal kan een aanvaller die een databasedump kan maken ook bij andere delen van het systeem komen. De kans is redelijk aanwezig dat hij ergens in de code de salt in plain text vindt. Dan is het een kwestie om een nieuwe rainbow table te maken met als input een bestaande rainbow table input (dus de wachtwoorden die als input zijn gebruikt) met de gevonden salt eraan geconcatineerd. Laat dat proces een paar dagen op Amazons platform reutelen en je hebt een nieuwe (custom) rainbow table die je kunt matchen tegen de gevonden waardes in je gestolen database. Conslusie: het duurt langer, maar dat is het dan ook wel (mits de aanvaller de salt ook gestolen krijgt, anders kan hij er inderdaad niks meer mee).
Een rainbow table is een database met daarin miljoenen strings met bijbehorende hashes
Eerder in de orde van grootte van biljarden hashes. Saillant detail is overigens dat al die hashes niet opgeslagen zijn. Een rainbow table bestaat uit hash chains waarvan alleen de eerste input en de laatste output zijn opgeslagen. Zo'n hash chain wordt berekend door met een willekeurig wachtwoord te beginnen en die vervolgens keer op keer te hashen en te "reverse hashen". Zo'n reverse hash is simpelweg het herinterpreteren van de bits van de hash om op die manier een string te krijgen die weer mogelijk als wachtwoord gebruikt zou kunnen worden.

Een voorbeeld van een chain:
"geheim" => 3ef213b4 => "pq4rsb" => 236d2ab4 => "asdf6hj" => b5960af4
Dus je slaat "geheim" en b5960af4 op.

Als je dan een hash van iemand's wachtwoord weet, dan ga je vanuit die hash de rest van de chain uitrekenen. Als je uiteindelijk op een waarde terecht komt die in je rainbow-table staat, dan weet je dat die chain overeenkomt met een van je chains in je rainbow-table. Nu je weet welke chain dat is, en je het begin van die chain weet, dan kun je vervolgens weer de hele chain aflopen totdat je weer bij de hash bent uitgekomen. De voorlaatste stap is het oorspronkelijke wachtwoord.
Als we bovenstaande chain als voorbeeld nemen en de hash was 236d2ab4, dan kom je uiteindelijk op de hash b5960af4 die in je database staat, met als beginpunt "geheim". Vervolgens ga je weer vanuit "geheim" doorrekenen en kom je na het hashen van "pq4rsb" weer op de oorspronkelijke hash: 236d2ab4. Dus "pq4rsb" was het wachtwoord.
Ik zou me niet onmiddellijk op collisions concentreren als SO. Ik denk dat het gebrek aan salts een groter probleem vormen. En dat valt wel gemakkelijk te illustreren. Gewoon ergens een website zoeken met rainbow tables voor het hashalgoritme in jouw organisatie. En dan een wachtwoord pikken dat in die rainbow tables zit bij de aanmaak van een nieuwe user.
Ik snap het ook echt niet, hoe kan het dat je hier op school in je eerste computer security vak (hier verplicht in het 2e jaar van je bachelor) als eerste les krijgen dat je wachtwoorden gesalt moet opslaan en dat chique database admins van grote bedrijven dit toch elke keer vergeten? Ook voor snel gegroeide startups geen excuus want migreren van een ongesalte naar een gesalte database is niet moeilijk en hoeven je gebruikers niet eens te merken

van:
hash(wachtwoord)

naar:
hash(hash(wachtwoord) + salt)
Omdat computer security geen verplicht vak was toen de database admins van grote bedrijven hun opleiding volgden. En als het al een verplicht vak was, dan was er in die tijd wellicht nog geen sprake van salts.
Het is heel vaak zo dat pas afgestudeerden theoretisch veel beter up-to-date zijn dan mensen die al een paar jaar hun vak uitoefenen.
moet dat niet zijn

van:
hash(wachtwoord)

naar:
hash(wachtwoord + salt) + salt ?
of
salt + hash(wachtwoord + salt)
of
salt op random positie in de hash hierna + hash(wachtwoord + salt)
of m.a.w.: je originele salt moet ergens in de hash zitten toch?

bvb http://phpsec.org/articles/2005/password-hashing.html
function generateHash($plainText, $salt = null)
{
if ($salt === null)
{
$salt = substr(md5(uniqid(rand(), true)), 0, SALT_LENGTH);
}
else
{
$salt = substr($salt, 0, SALT_LENGTH);
}

return $salt . sha1($salt . $plainText);
}
Idealiter wel, maar dat kan hier niet. Het originele wachtwoord is (hopelijk) niet beschikbaar, dus je kan nergens iets doen als hash(wachtwoord+salt), omdat je enkel hash(wachtwoord) tot je beschikking hebt.
Het originele wachtwoord is bekend op het moment dat de gebruiker inlogt en wordt geverifieerd?
Waardoor het wachtwoord van de gebruiker dus onveilig blijft tot hij een keer inlogt. Lijkt me niet echt een ideale situatie.
Tja, je kunt wachtwoorden na verloop van tijd toch ongeldig verklaren? Zo hebben de frequente gebruikers er geen last van. De andere gebruikers moeten opnieuw een wachtwoord instellen via hun e-mail adres en secret question of zo.

Niet ideaal, maar het kan dus wel.
Maar waarom probeer je een krampachtige oplossing te verzinnen voor een on-existent probleem? Gewoon hash(hash(wachtwoord) + salt) opslaan, is iedereen meteen veilig. En dus ook niet dat mensen tijdelijk onveilig zijn tot de expiration date is verstreken, waarna je dus ook weer iets moet hebben draaien dat regelmatig die dingen opschoont, etc.

[Reactie gewijzigd door .oisyn op 13 juni 2012 17:05]

Waar het om gaat is dat een site alleen hash('wachtwoord') weet, en dus niet 'wachtwoord' kan achterhalen, wat wel nodig is als hij hash('wachtwoord' + salt) wil berekenen. Het kan alsnog wel, maar dat vereist een login van de gebruiker (die dan 'wachtwoord' naar de site stuurt zodat de migratie naar gesalte wachtwoorden plaats kan vinden)

Voor een "offline" migratie is het handiger om de salt gewoon achter het gehashte wachtwoord te plakken, en dan nog een keer te hashen. Oftewel: hash(hash('wachtwoord') + salt)
m.a.w.: je originele salt moet ergens in de hash zitten toch?
Dat kan. Je kunt er ook gewoon een apart database-veld voor maken oid. Je zult de salt idd op een of andere manier ook op moeten slaan.

[Reactie gewijzigd door .oisyn op 13 juni 2012 11:42]

Inderdaad een goede oplossing.. Als je dan echter toch aan het omzetten gaat kun je er beter gelijk ook even een pepper bij ingooien, zodat ze geen site-specifieke rainbow tables kunnen gaan genereren.
van:
hash(wachtwoord)

naar:
hash(hash(wachtwoord) + salt + pepper)

pepper kan dan dus iets user specifieks zijn zoals userid/name/aanmaakdatum
Het idee van een salt is al dat hij hash-specifiek is, anders heeft het niet bijzonder veel nut.
Goed zo jongen!

Jammer dat er eerst zo'n hack nodig is.
Open, Snel, Daadkrachtig.

Valt me alles mee, wat mij betreft goed behoud van een 'professioneel' karakter. Dat het je overkomt is 1, er goed naar handelen is een tweede.
Oneens mbt de openheid. Ik heb enkel via nieuwsmedia mogen vernemen dat er een beveiligingslek is geweest. Dat vind ik niet transparant.
Nou, dan ben je zeker niet op LinkedIn geweest de afgelopen dagen. Gisteren bijvoorbeeld zag ik nog prominent de mededeling bovenaan de site, met keurig een linkje dat je maar 1x hoeft aan te klikken en je krijgt een mailtje om een nieuw wachtwoord in te stellen. Heel uitgebreid was die mededeling niet, maar weldegelijk directe klant-communicatie dus.
Afdoende klant-communicatie is in dit soort gevallen wat mij betreft alleen een melding per e-mail. Als je de site niet zo gek vaak bezoekt (wat denk ik voor de meeste gebruikers van de site zal gelden, het is tenslotte een zakelijk ding en geen facebook), kun je de melding dus compleet gemist hebben terwijl er wel een kans is dat je wachtwoord op straat ligt.
Ja, die prominente melding is er. Verdere communicatie is nul komma nul vanuit LinkedIn zelf. Toen de hack hier op Tweakers gemeld werd was er helemaal niets te vinden op hun homepage.

Vrijwel iedere dag wordt ik gemaild met contacten, nieuwsfeitjes, etc door LinkedIn. Dat gaan sinds dit lek gewoon ongestoord door, zonder ook maar een hint dat er wat mis is.
Niet waar, stond gewoon netjes een blog op hun site, en daarnaast rapporteerden sommige mensen dat ze een email hadden gehad van LinkedIn, volgens mij.
Open, snel en daadkrachtig. Dat zijn nou precies niét de drie termen die ik aan LinkedIn zou toeschrijven in deze zaak. Ze reageerden laat en wollig, zonder echt daadkracht te tonen en zonder volledige opengheid van zaken te geven. IMHO hebben ze juist heel veel credits verspeeld door hier zo amateuristisch mee om te gaan wat betreft techniek en communicatie.
Dit was een 'textbook mistake'. Honderden zijn al voorgegaan en zijn aan de schandpaal genageld, want hier wordt in elk boek voor gewaarschuwd. Het is onbegrijpelijk dat die fout toch nog gemaakt wordt. Alleen een hobbyist die zich niet inleest in de materie, die maakt deze fout misschien nog.

"Als het kalf verdronken is, dempt men de put." En dat is professioneel?
Nou, zo open vind ik dit allemaal niet verlopen. De communicatie naar gebruikers wordt aan de media overgelaten. Op de homepage was eerst niets te vinden en nu alleen een linkje.
To change your password and take advantage of our enhanced security measures, click here.
Verder geen uitleg "uit de eerste hand".

Dus om ook even in te haken op een andere discussie hier: het is me nu dus niet 100% duidelijk of ik inderdaad weer een nieuw password (vorige week uiteraard gelijk gedaan) aan moet maken om de salt in de hash te krijgen. De commentaren hier lijken aan te geven dat het technisch mogelijk is om ook een salt aan de bestaande hash toe te voegen. Dat is bij LinkedIn blijkbaar niet gedaan?

Wat communicatie betreft is er dus nog wel wat te verbeteren.
Laat de ongezouten opmerkingen maar komen. :+
Oftewel; eerst ligt je wachtwoord op straat en wijzig je hem (op advies van LinkedIn) en vervolgens blijkt je nieuwe wachtwoord niet te zijn gesalt. |:(
Nu maar hopen dat in de tijd tussen het nieuwe wachtwoord opstellen en het salten er niet nog een beveiligingslek is geweest. :/
wie zegt dat je opgeslagen wachtwoord niet gesalt is? Ze maken het alleen nú wereldkundig.
Maar je wachtwoord lag niet eens op straat. Bij PSN hack zeiden ze ook dat de wachtwoorden in plain text waren opgeslagen, waren allemaal leugens. Uiteindelijk heeft niemand gegevens kwijtgeraakt of hun CC gegevens gestolen.
Snel en netjes. Maar goed Linkedin zal altijd wel een risico blijven van aanvallen denk ik zo, ook al is het alleen maar om aan te geven dat er een lek in de beveiliging zit van meerdere sociale media sites.
Hoe is het mogelijk dat zij gehashte wachtwoorden zomaar kunnen voorzien van een salt? Een wachtwoord hashen met een salt is toch enkel mogelijk wanneer ze het plainttext wachtwoord hebben?
door de hash te salten en nog een keer te hashen
zie ook http://stackoverflow.com/...-existing-password-hashes
Niet als ze het al gehaste wachtwoord + salt gebruiken en dat geheel nog eens hashen. Oftewel in pseudocode:

hash = sha1(salt + sha1(wachtwoord));

De sha1(wachtwoord) hebben ze al, dus salten zou geen probleem moeten zijn.
Sterker nog, het volgende heeft zelfs weinig nut:

hash = sha1(wachtwoord + salt)

Met die (veelgebruikte) methode sluit je niet per definitie rainbow-tables uit, aangezien de standaard tables je dan simpelweg het wachtwoord + de salt teruggeven. En aangezien de salt in veel gevallen simpelweg een unieke ID is kan je zo achterhalen welk deel het wachtwoord is welk deel de salt.

Zeker als je een grote range aan hashes hebt waar een rainbow-table resultaten over teruggeeft is het vaak eenvoudig om het patroon te herkennen, waarna je salt weinig meer toevoegt.

Let wel: er zijn vele stappen mogelijk om dit te versterken (lange salt, dynamische lengte etc), ik beschrijf enkel de situatie die helaas vaak voorkomt. Enkel salten op de manier die ik hierboven beschrijf levert slechts marginale extra veiligheid.
Pardon? Dat mag je mij 's laten zien, hoe je uit een willekeurige hash m.b.v. een rainbow table het originele wachtwoord en de willekeurige salt kan krijgen.

eab7780e711d8a5ebefe0f59e40498580d813e42

Ga je gang.

Zal het nog simpeler maken. Het wachtwoord hier is "password", wat is de salt?

Rainbowtables werken bij de gratie dat je in een (geindexeerde) database snel een lookup kan doen van een bepaalde hash. Als je daar weer willekeurige salts bij moet gaan proberen ben je weer terug bij af: brute-forcen.
Ik heb hier geen rainbow-table tot mijn beschikking, maar laten we het eens omkeren met een voorbeeld.

Originele wachtwoord: password
Salt: 1234
Hash: sha1(password1234) = e6b6afbd6d76bb5d2041542d7d2e3fac5bb05593

Een rainbow-table zou zomaar deze hash kunnen herleiden tot "password1234", aangezien het een simpele string is die gehashed is, zonder poespas. Dat een deel ervan de salt is doet er niet toe voor die table, voor de hacker wel.

Indien ik een paar van dit soort hashes kan decrypten zie ik snel genoeg een patroon verschijnen in de strings die gehashed worden: [text]*[0-9]{4}

Het moge duidelijk zijn dat de laatste vier cijfers dan altijd de salt zijn, en het deel ervoor het wachtwoord. Wat heb je nog meer nodig?

Nogmaals: hier is veel tegen te doen, ik geef enkel aan dat het vaak verkeerd geïmplementeerd wordt. De kans is ook kleiner dat de hash zich in de rainbow-table bevindt, maar dat komt puur doordat het een relatief langere string is. Verder zijn er totaal geen restricties die beletten dat de hash zich in een table bevindt.

[Reactie gewijzigd door Ram0n op 13 juni 2012 11:42]

Er wordt hier gesproken over het salten van de hashes van wachtwoorden, niet over het salten van de originele wachtwoorden. Jouw voorbeeld gaat in dat geval niet op.
Dit is genoeg toch? De salt verschilt per user, dus daardoor krijgt "password" voor elke user een andere hash, waardoor de rainbow attack niet meer werkt.
Is dat de misschien 'extra laag van beveiliging'? ;)
Waarschijnlijk hebben ze iets ingebouwd dat als je je ww wijzigd of als je inlogd met je ww, op dat moment weet het script je ww, het ww wordt geverifieerd met de oude en nieuwe methode. Komt deze overeen met de oude methode, dan gooi je er een salt overheen en update je het record.
Ik vermoed dat ze het salten doen bij inloggen of bij het wijzigen van het wachtwoord.
Nee, dus lees voordat je onzin uitkraamt?
Dat was ook mijn eerste idee. Ik denk dat ze aan het gehashte wachtwoord salt hebben toegevoegd en dan opnieuw gehashed. Op deze manier moeten ze natuurlijk wel 2 keer een hash functie uitvoeren wat meer tijd vergt.
Dit zal wel dynamisch gebeuren zodra de klant inlogt, dan is het plaintext password tijdelijk beschikbaar.
Dat klopt.

Waarschijnlijk zal FB in de DB een extra veld met salt hebben opgenomen die leeg is voor 99.99% van de gebruikers. Als je NU je wachtwoord veranderd zal een salt worden gemaakt en dus zal het veiliger zijn.

Ook kunnen ze vinden dat je cookie verlopen is, en je opnieuw laten inloggen, zodoende hebben ze je passwd in plaintext en kunnen ze alsnog salten.
Hoe is het mogelijk dat zij gehashte wachtwoorden zomaar kunnen voorzien van een salt? Een wachtwoord hashen met een salt is toch enkel mogelijk wanneer ze het plainttext wachtwoord hebben?
Op ongeveer dezelfde manier als Tweakers.net gebruikte om van md5 af te stappen gok ik.
plan: Development-round-up - iteratie #4
Er moet een extra kolom gemaakt worden met een 'random' salt erin. Verder moet dan de bestaande hash aan de salt toegevoegd worden en nogmaals gehasht worden. Deze uitkomst komt dan in het wachtwoord veld.

In een 'overnight' batch kan dat gewoon gebeuren zonder dat iemand er last van heeft
Wat niet duidelijk wordt aangegeven is of ze per gebruiker een unieke salt hebben gekozen, of een salt die identiek is over de hele userbase. De eerste optie heeft natuurlijk de voorkeur aangezien er anders alsnog een rainbow table kan worden gemaakt specifiek voor LinkedIn.
Een SHA-1 rainbow table maak je niet snel even.
Het is ook niet zo nuttig om dat speciaal voor 1 website te doen, als je toch alle hashes al hebt. Dan is het nuttiger om gewoon te bruteforcen (omdat i/o in het maken van rainbow tables met gespecialiseerde hardware best de bottleneck kan zijn).

Maar je hebt gelijk, het is nuttig om de salt ook een beetje te variëren.
Een gepeperde actie :Y)
Stop is met die ongezouten humor :p
En nou opzouten met die flauwe woordgrappen! :+
Gezien de salt wordt toegevoegd voordat het wachtwoord gehashed is, maar ze het nu achteraf gedaan hebben, zal er wel een omweggetje in het systeem gemaakt moeten zijn?
Absoluut niet, het enige wat nodig is is een extra veld met de salt. Verder kan je dan alles salten op bovenstaande manier.

Op dit item kan niet meer gereageerd worden.



Populair:Apple iPhone 6DestinyAssassin's Creed UnityFIFA 15Nexus 6Call of Duty: Advanced WarfareApple WatchWorld of Warcraft: Warlords of Draenor, PC (Windows)Microsoft Xbox OneApple iOS 8

© 1998 - 2014 Tweakers.net B.V. Tweakers is onderdeel van De Persgroep en partner van Computable, Autotrack en Carsom.nl Hosting door True

Beste nieuwssite en prijsvergelijker van het jaar 2013