Avatar billede n-emy Nybegynder
21. december 2010 - 10:22 Der er 12 kommentarer og
1 løsning

Kryptering og predefined statements

Hej derude

Jeg sidder med nogle ting jeg har kigget lidt på indenfor det seneste stykke tid, og kunne godt tænke mig eksperters syn på sagen.

I øjeblikket bruger jeg sha1() funktionen til kryptering af mine passwords mm., men kunne godt tænke mig at prøve kræfter med crypt()-funktionen, der understøtter sha512, men når jeg læser http://dk.php.net/manual/en/function.crypt.php forstår jeg ikke hvorfor den vil have mig til at skrive (eksempelvis)

echo 'SHA-512:      ' . crypt

Hvorfor skal der echo før crypt? Har prøvet det og kunne godt få det til at virke, men jeg prøver at forstå hvorfor sha-512 skal printes? Jeg kunne også godt tænke mig at få funktionen ind i denne funktion:

function hashPassword($password, $salt = '') {
    if ($salt == '') {
        $salt = sha1(uniqid(microtime()));
    }
    $salt = substr($salt,0,20);
    return $salt.sha1($salt.$password);
}

Har prøvet med lidt forskelligt dog uden held.


Derudover kunne jeg godt tænke mig at vide lidt mere om predefined statements, har læst lidt omkring og det skulle vist være det nye sort i bekæmpelsen af SQL-injections osv., men hvordan skulle følgende kode eksempelvis skrives?

(eksempel fra php.net)
$string = $_REQUEST['string'];
$binary = file_get_contents($_FILE['file']['tmp_name']);

$string = mysql_real_escape_string($string);
$binary_hex = bin2hex($binary);

$query = "INSERT INTO `table` (`key`, `string`, `binary`, `other`) VALUES (NULL, '$string', 0x$binary_hex, '$other')";

(Nu søgte jeg lige en ekstra gang på php.net for at finde noget testkode fra predefined statements men kunne ikke finde noget, så er blevet lidt i tvivl om hvorvidt det hedder predefined statements det jeg leder efter, men jeg håber de fleste ved hvad jeg mener alligevel =) )

På forhånd mange tak for hjælpen :)
Avatar billede majbom Novice
21. december 2010 - 10:46 #1
du kan jo bare bruge crypt, lige som du bruger sha1: $krypteret_pass = crypt('mit_password', 'salt_streng');


prepared statements:

$stmt = $mysqli->prepare("INSERT INTO table VALUES (?, ?, ?)");
$stmt->bind_param('sssd', $var1, $var2, $var3);

$var1 = 'var1';
$var2 = 'vaR2';
$var3 = "var3";

$stmt->execute();
$stmt->close();
Avatar billede n-emy Nybegynder
21. december 2010 - 11:01 #2
splazz:

Mange tak, men hvordan vælger den så sha512 med crypt for der er jo mange forskellige krypteringsformer med crypt så vidt jeg har forstået?

Og mange tak for predefined :)
Avatar billede majbom Novice
21. december 2010 - 12:30 #3
det kommer an på hvordan serveren er sat op, du kan prøve at køre denne kode:

<?php
if (CRYPT_STD_DES == 1) {
    echo 'Standard DES: ' . crypt('n-emy') . "\n";
}

if (CRYPT_EXT_DES == 1) {
    echo 'Extended DES: ' . crypt('n-emy') . "\n";
}

if (CRYPT_MD5 == 1) {
    echo 'MD5:          ' . crypt('n-emy') . "\n";
}

if (CRYPT_BLOWFISH == 1) {
    echo 'Blowfish:    ' . crypt('n-emy') . "\n";
}

if (CRYPT_SHA256 == 1) {
    echo 'SHA-256:      ' . crypt('n-emy') . "\n";
}

if (CRYPT_SHA512 == 1) {
    echo 'SHA-512:      ' . crypt('n-emy') . "\n";
}
?>


for at se hvilken metode din server er sat op til...
Avatar billede repox Seniormester
21. december 2010 - 12:51 #4
En indskudt bemærkning - kig hellere på hash() som understøtter alle de algoritmer der er smidt på serveren; og du har nem kontrol over det i forhold til crypt() (IMO).

Af ren nysgerrighed, hvordan bruger du så din hashPassword() funktion? Genererer du bare et krypteret kodeord? Hvad gør du med det bagefter?
Avatar billede majbom Novice
21. december 2010 - 12:57 #5
-> repox - det bliver i hvert fald svært at tjekke et indtastet PW op imod noget der tidligere er genereret med den funktion :)
Avatar billede repox Seniormester
21. december 2010 - 13:06 #6
#5
Det var jo netop min tanke :p Den løsning jeg selv bruger til mit brugersystem er godt nok total overkill, men når folk er så fokuseret på sikkerhed, så er der ingen spørgsmål til det ;)

MEn overordnet set, genererer jeg et tilfældigt 128 tegn langt salt, gemmer det i databasen sammen med det SHA1 krypterede kodeord der er parret sammen med det salt (jeg er ikke lige kommet til det punkt hvor jeg har fundet en smart løsning på at opdatere det til at køre SHA256/SHA512 uden at genere mine brugere for meget :p ) Naturligvis køres det hele i prepared statements. :)
Avatar billede n-emy Nybegynder
22. december 2010 - 10:26 #7
Tak begge to :)

Repox:

Bruger følgende kode til at tjekke passwords når brugeren er logget ind, det har virket fint indtil videre men er der problemer med det?

$codedb = $dbuser[password];
$user_input_hashed = hashPassword($_POST[password], $codedb);

if($user_input_hashed == $codedb) {
//Session register
}
//Har ikke posted hele koden men jeg smider ikke $_POST[password] ufiltreret ind det var bare for at vise hvad der var inputtet fra formen =)

Mht. det du gør, hvis en hacker får adgang til din database vil han jo så have brugerens salt og kode på samme tid gør det det så ikke lettere for ham at bryde passworded? - Du har mere forstand på det end mig så sikkert ikke, men man bliver jo kun klogere af at spørge =)
Avatar billede majbom Novice
22. december 2010 - 10:43 #8
du genererer jo et nyt salt hver gang og det kan kun blive unikt da du bruger microtime - ergo kan du ikke få samme hash to gange.
Avatar billede repox Seniormester
22. december 2010 - 10:49 #9
#7
Jeg forstår ikke helt din kode - min logik siger mig at det der aldrig vil virke, så umiddelbart må der mangle noget essentielt for at gøre koden brugbar.

Det som jeg opfatter er at du henter værdien fra feltet 'password' i din tabel fra databasen ($codedb). Den kode, tager du så og salter samt hasher i din funktion som tildeler returværdien til variablen $user_input_hashed. De to kan unægteligt kun være to forskellige værdier og derfor vil din if($user_input_hashed == $codedb) aldrig kunne evaluere som sandt?

Ud over det, skal du huske at bruge quotes rundt om dine array indexes - altså, $dbuser["password"] og $_POST["password"]; det kan godt være det virker i sin nuværende form, men i større/ukendte projekter kan det give mange uventede resultater.

Med hensyn til min kode, så er der ikke nogen sikkerhedsrisiko i det. For det første har hver bruger sit eget unikke salt; for det andet har hver bruger også sit eget valgte kodeord som jeg gemmer den saltede og krypterede version af. Sikkerheden består i at jeg aldrig vil kunne se kodeordet - og en 'hacker' ville få ualmindelig svært ved at at gætte sig frem til en hashet udgave af en tilfældig 128 tegn lang streng + en ukendt kodeordssammensætning. Du kan jo ikke dekryptere en hashet streng.
Avatar billede n-emy Nybegynder
22. december 2010 - 11:45 #10
Det er jo kun hvis salt inputtet i funktionen er tom at den genererer microtime.

Når jeg opretter en bruger gemmes saltet på 20 tegn sammen med det hashede password og når jeg så angiver kodeordet i databasen som salt i tjek-password funktionen tager den det 20 tegns lange salt ud fra strengen og tjekker kodeordet. Er det mig der er helt galt på den?

Kunne godt være jeg sku prøve noget lignende repox, mht. quotes rundt om array indexes ved jeg det godt, glemmer det bare altid :)
Avatar billede repox Seniormester
22. december 2010 - 11:53 #11
Jeg vil mene du er forkert på den - du kan jo ikke dekryptere et hash; ellers misforstår jeg dig.
Kan du prøve at give et eksempel på data fra tabellen? Det kan være det kaster lidt lys over sagen...
Avatar billede n-emy Nybegynder
29. december 2010 - 19:30 #12
Det her er et eksempel på et kodeord:

a74cd59a7482c121b737ea9f33c1e429ce945ac9dcdf8afbf463

hvor de 20 første tegn er saltet (eller det er i hvertfald meningen med scriptet) og de resterende er selve kodeordet (hejsa)

Beklager det sene svar men der har været så meget med jul osv. :)

Ville det være smartere at gemme saltet i sit eget felt?
Avatar billede n-emy Nybegynder
25. november 2012 - 19:36 #13
Lukker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester