| Visa föregående ämne :: Visa nästa ämne |
| Startad av: |
Meddelande |
marabou


Medlem i: 3146 dagar Från: Sveriges framsida
Status: Offline
#711581
|
Skrivet: 2011-08-11 11:17
Ämne: Hasha lösenord med bcrypt
|
|
|
Det pågår många diskussioner om hur man ska lagra lösenord. Hashmetoder som md5, sha1, sha512 osv. är relativt lätta att knäcka även om man använder salt.
Säkerhetsexperter rekommenderar istället bcrypt som är baserat på Blowfish-krypteringen, men bcrypt är ingen kryptering utan en hashmetod ("envägskryptering").
Fördelen med bcrypt är att den kräver salt och att det är ruskigt långsam (vilket i praktiken gör den omöjlig att knäcka). En av bcrypts fördelar är att den kan göras långsammare i takt med att hårdvara blir snabbare.
Läs mer om bcrypt här:
http://codahale.com/how-to-safely-store-a-password/
Så hur använder man bcrypt i PHP?
1: <?php 2: 3: function bcrypt($password, $salt, $rounds=12) { 4: 5: // Kolla om bcrypt är tillgängligt på servern 6: if (CRYPT_BLOWFISH != 1) { 7: throw new Exception("bcrypt stöds inte. Se http://php.net/crypt"); 8: return; 9: } 10: 11: // Kolla så rounds är inom tillåtet intervall 12: if ($rounds < 4) 13: $rounds = 4; 14: else if ($rounds > 31) 15: $rounds = 31; 16: 17: // Skapa ett prefix för att tala om för crypt att vi vill använda Bcrypt 18: $salt_prefix = sprintf('$2a$%02d$', $rounds); 19: 20: // Kolla om saltet innehåller ogiltiga tecken: 21: if (!preg_match('#^[A-Za-z0-9./]{22}$#', $salt)) { 22: // Saltet är inte bcrypt-säkert. Gör om till 22 tecken (A-Za-z0-9./) 23: $new_salt = base64_encode($salt); 24: if (strlen($new_salt) < 22) 25: $new_salt .= base64_encode(md5($salt)); 26: $salt = substr($new_salt, 0, 22); 27: $salt = str_replace(array('+', '-'), '.', $salt); 28: $salt = str_replace(array('=', '_'), '/', $salt); 29: } 30: 31: // hasha lösenordet med bcrypt 32: return crypt($password, $salt_prefix.$salt); 33: 34: }
|
Sedan för att kolla om lösenordet är korrekt, exempel:
1: <?php 2: 3: $statiskt_salt = 'En sträng som kan användas som salt...'; 4: 5: $anvandarnamn = $_POST['username']; 6: $losenord = $_POST['password']; 7: 8: $salt = $statiskt_salt . $anvandarnamn; 9: $hash = bcrypt($losenord, $salt); 10: 11: if ($hash == $losenordet_fran_databasen) 12: echo "Rätt lösenord"; 13: else 14: echo "Fel lösenord";
|
Som ni förstår är ovanstående endast ett exempel och måste självklart anpassas till er egen kod, men bcrypt-funktionen kan användas som den är.
Notera att saltet för bcrypt måste vara 22 tecken A-Z a-z 0-9 samt . och /.
Dock har jag skrivit så min bcrypt-funktion gör om vilket salt som helst till att vara 22 tillåtna tecken. Alltså kan ni använda det salt ni använder idag  |
|
|
_________________ "Never argue with stupid people. They will bring you down to their level and beat you with experience."
- Mark Twain |
| Till toppen på sidan |
|
Sawny
Medlem i: 1002 dagar
Status: Offline
#711617
|
Skrivet: 2011-08-11 18:07
Ämne:
|
|
|
| Citat: |
| Hashmetoder som md5, sha1, sha512 osv. är relativt lätta att knäcka även om man använder salt. |
EDIT2:
Räknade fel, har ändrat så det blev rätt nu. Tack emilV.
Ändrade även salt längden från 10 till 15. Om längden är 10 så går det på max 42 dagar om man gör 500 miljarder md5's per sekund.
Nej, inte om man använder salt.
Ett salt som är på 15 tecken, a-zA-Z0-9 + ?!$@% tar 16 million, 2 thousand and 517 år att knäcka.
67 möjliga tecken ^ 15 tecken långt salt = 2461059085914092013369600043 kombinationer.
Även om du knäcker 5 triljoner (5000000000000) md5s per sekund så skulle det ta ca 16002517 år att vara helt säker på att ha knäckt bara saltet.
http://www.wolframalpha.com/input/?i=round%2867+^+15+%2F+5000000000000+%2F+60+%2F+60+%2F+24+%2F+356%29
EDIT1:
Dock gäller det ju att hackaren inte har tillgång till saltet.
Långsammare krypteringar skyddar ju då användarna som valt svaga lösenord.
Senast ändrad av Sawny den 2011-08-12 14:09, ändrad totalt 1 gång |
|
|
_________________ HTML, CSS, PHP, JS |
| Till toppen på sidan |
|
hallis

Medlem i: 3686 dagar Från: Stockholm
Status: Offline
#711633
|
Skrivet: 2011-08-12 09:20
Ämne:
|
|
|
| Sawny skrev: |
EDIT:
Dock gäller det ju att hackaren inte har tillgång till saltet.
Långsammare krypteringar skyddar ju då användarna som valt svaga lösenord. |
Om hackaren inte har tillgång till saltet skall det absolut inte spela någon roll om användaren har ett svagt lösenord eller ej, du saltar ju med en unik sträng som gör att lösenordet inte skall gå att gissa.
När man talar om hur säkert en lösenordshantering är räknar man alltid med att hackaren har tillgång till allt. Sen ställer man inte frågan OM lösenordet går att hacka utan hur långtid det tar, därför är en långsam funktion att föredra.
Jag ska dock tillägga att jag inte lever som jag lär, jag använder sha1 med dynamiskt och statisk salt. Dock sätter jag höga krav på att användarens lösenord skall vara >6 tecken långt innehålla versaler och gemener samt siffror. |
|
|
_________________ Utvecklingsbloggen |
| Till toppen på sidan |
|
Jalet
Medlem i: 3160 dagar Från: Järfälla, Kallhäll
Status: Offline
#711634
|
Skrivet: 2011-08-12 09:45
Ämne:
|
|
|
| hallis skrev: |
| ...Dock sätter jag höga krav på att användarens lösenord skall vara >6 tecken långt innehålla versaler och gemener samt siffror. |
Detdär med att tvinga användre att använda vissa tecken vet jag inte om jag tror på riktigt. Användare som tvingas använda vissa tecken tenderar att skriva upp sina lösenord i dokument eller på papper. Därav så finns lösenordet i klartext och för hackaren är det då inte speciellt svårt att ta sig in i systemet förklädd till en användare.
Säkerheten bör därför istället ligga på servernivå, gör allt du kan för att hålla hackern borta från servern & se till att kryptera lösenordet med både statiska & dynamiska salt. Detta har dock gång på gång visats vara svårt då hackare gång på gång tagit sig in i långt mer avancerade system (NASA, FBI CIA) än de som vanligvis diskuteras på detta forum.
Sen kan även en idé vara att lösenorden byts ut med jämna mellanrum.
Hur pass säkert systemet måste vara ska sjävlklart ställas i förhållande till applikationens syfte & graden av känslig information som finns där. |
|
|
|
| Till toppen på sidan |
|
EmilV


Medlem i: 3791 dagar Från: Upplands Väsby
Status: Offline
#711636
|
Skrivet: 2011-08-12 09:54
Ämne:
|
|
|
| Bra funktion, marabou. Dock undrar jag om det är så smart att göra en massa magiskt med saltet inuti funktionen. Är det inte bättre att ha förvillkor till funktionen och tvinga programmeraren att göra rätt? |
|
|
_________________ Tänk!
EmilVikström.se | GeHjärta.se |
| Till toppen på sidan |
|
Sawny
Medlem i: 1002 dagar
Status: Offline
#711638
|
Skrivet: 2011-08-12 10:29
Ämne:
|
|
|
| hallis skrev: |
| Sawny skrev: |
EDIT:
Dock gäller det ju att hackaren inte har tillgång till saltet.
Långsammare krypteringar skyddar ju då användarna som valt svaga lösenord. |
Om hackaren inte har tillgång till saltet skall det absolut inte spela någon roll om användaren har ett svagt lösenord eller ej, du saltar ju med en unik sträng som gör att lösenordet inte skall gå att gissa.
Jag ska dock tillägga att jag inte lever som jag lär, jag använder sha1 med dynamiskt och statisk salt. Dock sätter jag höga krav på att användarens lösenord skall vara >6 tecken långt innehålla versaler och gemener samt siffror. |
Den unika strängen måste antingen genereras på samma sätt varje gång man loggar in, eller så måste den vara sparad någon stans. Om hackaren har tillgång till allt så spelar den unika strängen inte så stor roll.
Man kan ju kräva att användaren ska ha 6 tecken storasmå + siffror. |
|
|
_________________ HTML, CSS, PHP, JS |
| Till toppen på sidan |
|
intedinmamma
Medlem i: 1376 dagar Från: Göteborg
Status: Offline
#711639
|
Skrivet: 2011-08-12 10:32
Ämne:
|
|
|
Tänkvärt.  |
|
|
_________________ Statistiskt sett? Kanske. |
| Till toppen på sidan |
|
marabou


Medlem i: 3146 dagar Från: Sveriges framsida
Status: Offline
#711646
|
Skrivet: 2011-08-12 13:06
Ämne:
|
|
|
| EmilV skrev: |
| Bra funktion, marabou. Dock undrar jag om det är så smart att göra en massa magiskt med saltet inuti funktionen. Är det inte bättre att ha förvillkor till funktionen och tvinga programmeraren att göra rätt? |
Kan hålla med om att det vore bättre att programmeraren gör rätt från början men det blir mer kod varje gång man skall hasta ett lösenord och saltet med rätt tecken måste lagras någonstans. När jag skrev denna funktionen tänkte jag på hur jag själv gör och jag brukar använda användarnamn eller användar-id som dynamiskt salt, för då behöver jag inte lagra ytterligare ett salt någonstans. Därför känns det smidigt att bara kunna skicka med användarnanmnet och ett statiskt salt så rättar funktionen själv till det.
Om programmeraren själv skickar in ett korrekt salt så används det. |
|
|
_________________ "Never argue with stupid people. They will bring you down to their level and beat you with experience."
- Mark Twain |
| Till toppen på sidan |
|
hallis

Medlem i: 3686 dagar Från: Stockholm
Status: Offline
#711648
|
Skrivet: 2011-08-12 15:21
Ämne:
|
|
|
Läsvärt
| Sawny skrev: |
| Den unika strängen måste antingen genereras på samma sätt varje gång man loggar in, eller så måste den vara sparad någon stans. Om hackaren har tillgång till allt så spelar den unika strängen inte så stor roll. |
Just i det exemplet skrev jag "Om hackaren inte har tillgång till saltet" - det tar inte mycket längre tid att lista ut vJk24f#2" än "sommarnatt" om du har ett unikt sal likt KLjhsdaf785/(%98nJHSD+_:324 innan/efter om ingen känner till det.
Och i det stycket du inte valde att citera skrev jag "Sen ställer man inte frågan OM lösenordet går att hacka utan hur långtid det tar", oavsett hur långt/komplicerat lösenord du har kommer det gå att bryta ur, det är bara en tidsfråga. Därför skall man använda en långsam metod - inte för de som t ex har "sommarnatt" som lösenord. |
|
|
_________________ Utvecklingsbloggen |
| Till toppen på sidan |
|
|