Hem > PHP, Webbutveckling > Därför kan SHA-512 vara osäkert

Därför kan SHA-512 vara osäkert

Som många vet finns det mängder av hemsidor som säger sig kunna dekryptera envägs-kryptering (exempelvis md5 och sha1) till dess ursprungliga värde. Hur dem kan göra detta är inte så konstigt, när man gör ett hash tar man bara ursprungsvärdet och sparar det tillsammans med hashet som genereras. Ett väl känt exempel är password som ger 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8 när man kör det med sha1. Missuppfatta mig inte nu, man ska hasha lösenord och andra tillämpningar där envägskryptering är möjlig och är rimligt att göra, men gör det inte bekvämt för sig själv genom att gör något i stil med:

<?php
$pass_hash = md5($pass);
?>

Även om man slutar använda md5 mot starkare hash så som sha-512 hjälper det inte om det finns hemsidor som inte bara loggar sha1 och md5, utan även andra hash som sha-512 så som md5decrypter.co.uk.

Hur skyddar man sig?


Uppdatering 2020-07


Sedan artikeln skrevs har mycket hänt på säkerhetsfronten och därmed är delar av informationen utdaterad och anses inte som god säkerhets sed. För hashing av lösenord rekommenderas password_* funktioerna i PHP (även känd som password_hash). För att komma igång så rekommenderar jag guiden ”How to hash passwords in PHP” av Alex web develop.


Ursprunglig artikel 2011:

Om man studerar md5decrypter och liknande hemsidor kan man hitta vad för hash som kan dekrypteras. Vet man vilka dessa är, då vet man vilka metoder man inte ska använda. Ett urval på dessa metoder:

MD5($pass)
MD5x2 ($pass)
MD5x3($pass
MD5x4 ($pass)
MD5x5($pass)
NTLM ($pass)
LM ($pass)
MySQL5($pass)
SHA1($pass)
SHA1x2($pass)
SHA1x3($pass)
SHA256($pass)
SHA384($pass)
SHA512($pass)
RIPEMD160($pass)
md5(sha1($pass))
sha1(md5($pass))
md5($pass.$salt)
md5($salt.$pass)
md5(md5($pass).$salt)
md5(md5($salt).$pass)
md5($salt.md5($pass))
md5($salt.$pass.$salt)
sha1($pass.$salt)
sha1($salt.$pass)

När man har hittat en metod för att exempelvis hasha lösenord, se då till att inte använda sig av någon av följande hash-algoritmer då de vart och ett har en eller flera brister:

MD2
MD4
Adler
Crc32
Crc32b
Tiger128,3
Tiger128,4
Haval128,3
Haval128,4
Haval128,5
Ripemd128

Ett exempel på ett hash som jag anser är både rätt enkel och som samtidigt har en god säkerhet är följande hash:

<?php
define('HASH_SALT', 'Fyll i valfri stäng på minst 32 tecken som innehåller siffror (123), stora bokstäver (ABC) och specialtecken (!%@#) samt även gärna ÅÄÖ om så är möjligt. Saltet bör vara unikt och således inte innehålla ord som finns i något språk eller använda hemsidans/applikationens namn.');

$pass_hash = hash('sha256', hash('sha224', HASH_SALT . hash('gost',$pass) . $username) ) );
?>

Tanken med ovanstående hash är att jag använder fyra stommar. Första stommen är att använda mig av rätt ovanliga hash i tre lager, detta gör att det redan nu blir svårt att knäcka. Dock räcker detta inte, för att få grundläggande säkert måste vi använda oss av ett salt som är den andra stommen. Väljer man ett bra och unikt salt blir också hashen som genereras unika och därmed sätter hash-databaser så som md5decrypter.co.uk ur spel. Tredje och sista stommen är något som jag skulle kalla för ett dynamiskt salt. Den syftar till att göra varje hash unikt även i databasen. Även om det finns ett flertal användare som har samma lösenord (exempelvis password) kommer de att generera olika hash, detta eftersom att de har olika användarnamn. Den fjärde och sista stommen återkommer jag till.

För att sätta extra krydda på säkerheten kan man vara lite kreativ och sätta personlig touch på hashet. Ett exempel är att utnyttja moment 22:

<?php
define('HASH_SALT', 'Fyll i valfri stäng på minst 32 tecken som innehåller siffror (123), stora bokstäver (ABC) och specialtecken (!%@#) samt även gärna ÅÄÖ om så är möjligt. Saltet bör vara unikt och således inte innehålla ord som finns i något språk eller använda hemsidans/applikationens namn.');

$pass_hash = hash('sha256', hash('sha224', HASH_SALT . hash('gost',$pass . str_len($pass)) . $username) ) );
?>

I detta fall har jag valt som en enkel sak som att ta med antalet tecken som finns i lösenordet. Har man inte lösenordet då vet man inte hur många tecken lösenordet innehåller.

Om man vill kan man fortsätta och bygga ytterligare lager och så sätt ytterligare sätta lite extra säkerhet. Men man måste komma ihåg att oavsett hur många lager man använder får man aldrig glömma bort den fjärde stommen, och det är lösenord. Med rätt lösenord kommer man alltid in, även om man använder en hashmetod som nästan är omöjlig att knäcka. Om lösenordet är enkelt så som password eller 123456 är det knappt någon utmaning att ta sig in i ett system. Ställ alltid kravet att ett lösenord måste vara minst 8 tecken långt, innehålla stora och små bokstäver, siffror och specialtecken. Tillåt alltid så många specialtecken som möjligt och sätt aldrig en övre gräns på antalet tecken.

Slutpledering

Även om det är viktigt att hasha sin information på ett säkert sätt måste man komma ihåg att det inte ersätter övrig säkerhet. Syftet med att använda hash är att få ett mindre helvete för den eller dem som lyckas komma över informationen. Helst ska hashen inte kunna knäckas, men vet man hur informationen hashas är det också möjligt att få fram vad som lagrats i hashen. Därför brukar man säga att syftet med hash är att köpa sig tid innan någon eventuellt lyckas knäcka det. Tid som ska användas till för att säkra upp sina system och rutiner samt hunnit byta ut alla lösenord för användarna. Man kan säga att ett hash fungerar som en sista försvarslinje.

  1. Mattias
    juni 27th, 2011 i 02:02 | #1

    Mycket väl förklarat hur hasher fungerar!

  1. Inga trackbacks än.