Kryptering

Salt kryptering er en måde at sikre sig mod visse former for password hacking. Krypteringen foregår i flere trin – lad os kigge på dem et ad gangen.

1 – HTML input feltet

Lad os sige at vores bruger hedder Per – og Per vil oprette sig som nyt medlem på vores hjemmeside. Det første han skal gøre er at indtaste et brugernavn og et password – det kender vi allesammen. Det første vi som udviklere skal gøre, er at sikre os at det HTML input element vi bruger, er af typen password:

 <label for="password">Password:</label>
 <input id="password" name="password" required="" type="password" 
  placeholder="8 characters minimum" maxlength="8" size="8"/>

Når vi sætter size=”8″ og maxlength=”8″, sikrer vi os for det første at brugeren kun kan udfylde feltet med akkurat 8 karakterer. Det skal vi så lige huske at tjekke for når vi modtager

Når typen på et inputfelt sætte til “password”, optræder karaktererne skjult på skærmen, typisk som * eller •. Det eneste dette sikrer os imod er hackere som står lige bag ved brugeren og ser på skærmen. Men det gør de jo ikke så ofte, så det vi i virkeligheden skal fokusere på, er processen fra Per trykker “Send” til der oprettes en ny bruger i databasen.

Brug https…

Når Per trykker på send loades der en ny side på serveren – og her kan det allerede gå galt. Når serveren har et HTTPS certifikat, krypteres informationer fra side til side, og detr gør det meget vanskeligt at overvåge browserkommunikationen udefra.

Intruders exploit every unprotected resource that travels between your websites and your users. Images, cookies, scripts, HTML … they’re all exploitable.

Læs evt mere her

2 Serversiden

Når den næste side loader får serveren tilsendt et password – her 8 karakterer som Per selvfølgelig selv har fundet på. Lad os bare sige at Per er som så mange andre – han har valgt passwordet “12345678”.

2.a Escape strengen (undgå SQL injection)

Hvis Per nu selv var hacker kunne vi faktisk godt risikere at han skrev ting og sager i selve input felterne, som kan bryde ind i databasen. Det har vi delvis sikret os ikke sker ved at feltet kun accepterer 8 karakterer, men det er ikke så vanskeligt at lave om på som så meget andet. Tænk på at siden skal ende med at udføre noget SQL kode – det kunne for eksempel se sådan her ud:

INSERT INTO TABLE PERSON (brugernavn, password) VALUES ('Per', '12345678');

Der hvor de ting brugeren skriver i felterne kommer ind i billedet, er efter VALUES(‘ – det er nemlig her Per for eksempel skal skrive ‘Per’. Men lad os så sige at Per var virkelig god til SQL og i stedet for et rigtigt brugernavn skrev følgende i feltet:

admin%27+,%2712345678+%27%29 WHERE brugernavn=%27admin%27;+--

(%27 betyder  og %29 betyder ) og betyder udkommenteret. Dermed ville den færdige query se sådan her ud:

INSERT INTO TABLE PERSON (brugernavn, password) VALUES ('admin', '12345678') WHERE brugernavn='admin';--, '12345678');

Så ville der blive kørt en SQL query som i stedet for at oprette en ny bruger, skifter brugernavn og password på en eksisterende bruger med brugernavn ‘admin’ til admin/12345678. Det virker selvfølgelig kun, hvis brugernavnet admin findes i databasen – men det gør det somme tider.

Det fænomen kaldes SQL-injection, og det vil vi gerne undgå. Derfor er det første vi skal gøre at escape alle tegn i password strengen – så de ikke kan opfattes som SQL, men kun som en streng. I MySqli bruger vi metoden mysqli_real_escape_string():

$escapedPassword = mysqli_real_escape_string($_POST['password']);

Hvis Per havde været så fræk at forsøge ovenstående, ville han simpelt hen bare få sat sit brugernavn til: admin%27+,%2712345678+%27%29 WHERE brugernavn=%27admin%27;+–, hvilket jo ville være upraktisk for ham selv, men ligegyldigt for os.

2.b HASH passwordet

Eftersom Per har været rigtig doven og sat sit password til noget virkelig enkelt, er vi ikke så glade for at have hans password liggende ukrypteret i databasen. Derfor kan vi bruge en krypteringsfunktion til at gøre passwordet i databasen noget mere ulæseligt.

I Mysqli kan vi bruge funktionen hash:

$hashedPW = hash('sha256', $escapedPassword);

Hvor sha256 er en algoritme som NASA (selvfølgelig, hvem ellers) har udviklet, og som gør Per’s 12345678 til det noget mere ulæselige EF797C8118F02DFB649607DD5D3F8C7623048C9C063D532CC95C5ED7A898A64F

Før vi gør det vil vi imidlertid bruge metoden SALT til at skabe en reel uforudsigelighed i passwordet.

2.c SALT passwordet

FORDI hashing ikke er unik – hvis Per vælger 12345678 og Britta bagefter gør det samme, vil deres passwords begge være EF797C8118F02DFB649607DD5D3F8C7623048C9C063D532CC95C5ED7A898A64F. Derfor skal vi bruge noget tilfældighed – og her kommer SALT ind i billedet. Vi starter med at generere en fuldkommen tilfældig sammensætning af 32 bits med metoden random_bytes(32). Derefter laver vi disse 32 bits om til en Hexadecimal repræsentation med metoden bin2hex(bits).

$salt = bin2hex(random_bytes (32));

Nu har vi altså en helt tilfældig hexadecimal værdi, som vi gemmer i databasen sammen med brugernavn og adgangskode. Og i stedet for at nøjes med at hashe adgangskoden som ovenfor, så sætter vi lige passwordet sammen med det tilfældige SALT FØR vi gemmer passwordet. På den måde får vi en unik adgangskode:

# Sæt den sammen med det strippede kodeord i variablen $saltedPW
$saltedPW = $escapedPassword . $salt;

# Dan så et nyt krypteret kodeord med de to 
$hashedPW = hash('sha256', $saltedPW);

Når vi så skal logge Per ind igen, gør vi følgende:

  • Escape brugernavn og password fra webform
  • Hent SALT i databasen for brugernavnet
  • Sæt passwordet fra webformen sammen med SALT koden
  • Log personen med passwordet  hash(‘sha256’, password + SALT)

That’s how it goes…

 

Leave a comment