Zoeken…


Invoering

Omdat veiligere webservices het opslaan van wachtwoorden in platte tekst voorkomen, bieden talen zoals PHP verschillende (niet te ontcijferen) hashfuncties om de veiligere industriestandaard te ondersteunen. Dit onderwerp biedt documentatie voor een goede hashing met PHP.

Syntaxis

  • string password_hash ( string $password , integer $algo [, array $options ] )
  • boolean password_verify ( string $password , string $hash )
  • boolean password_needs_rehash ( string $hash , integer $algo [, array $options ] )
  • array password_get_info ( string $hash )

Opmerkingen

Voorafgaand aan PHP 5.5 kunt u het compatibiliteitspakket gebruiken om de functies password_* te bieden. Het wordt ten zeerste aanbevolen om het compatibiliteitspakket te gebruiken als u dit kunt.

Met of zonder het compatibiliteitspakket, is de juiste Bcrypt-functionaliteit via crypt() afhankelijk van PHP 5.3.7+, anders moet u wachtwoorden beperken tot alleen ASCII-tekensets.

Opmerking: als u PHP 5.5 of lager gebruikt, gebruikt u een niet-ondersteunde versie van PHP die geen beveiligingsupdates meer ontvangt. Werk zo snel mogelijk bij, u kunt uw wachtwoordhashets daarna bijwerken.

Algoritme selectie

Veilige algoritmen

Onzekere algoritmen

De volgende hashing-algoritmen zijn onzeker of ongeschikt voor het doel en mogen daarom niet worden gebruikt . Ze waren nooit geschikt voor wachtwoordhashing, omdat ze zijn ontworpen voor snelle digests in plaats van langzaam en moeilijk te bruten wachtwoordhashes.

Als u een van deze , zelfs inclusief zouten, gebruikt, moet u zo snel mogelijk overschakelen naar een van de aanbevolen veilige algoritmen.

Algoritmen die als onzeker worden beschouwd:

Sommige algoritmen kunnen veilig worden gebruikt als algoritme voor het verwerken van berichten om de authenticiteit te bewijzen, maar nooit als hashing-algoritme voor wachtwoorden :

  • SHA-2
  • SHA-3

Merk op dat sterke hashes zoals SHA256 en SHA512 ononderbroken en robuust zijn, maar het is over het algemeen veiliger om bcrypt of argon2 hash-functies te gebruiken, omdat brute-krachtaanvallen op deze algoritmen veel moeilijker zijn voor klassieke computers.

Bepaal of een bestaande wachtwoordhash kan worden opgewaardeerd naar een sterker algoritme

Als u de methode PASSWORD_DEFAULT gebruikt om het systeem het beste algoritme te laten kiezen om uw wachtwoorden mee te hashen, omdat de standaardsterkte toeneemt, wilt u misschien oude wachtwoorden opnieuw gebruiken als gebruikers inloggen

<?php
// first determine if a supplied password is valid
if (password_verify($plaintextPassword, $hashedPassword)) {

    // now determine if the existing hash was created with an algorithm that is
    // no longer the default
    if (password_needs_rehash($hashedPassword, PASSWORD_DEFAULT)) {

        // create a new hash with the new default
        $newHashedPassword = password_hash($plaintextPassword, PASSWORD_DEFAULT);

        // and then save it to your data store
        //$db->update(...);
    }
}
?>

Als de functies wachtwoord_ * niet beschikbaar zijn op uw systeem (en u het compatibiliteitspakket dat in de onderstaande opmerkingen is gekoppeld, niet kunt gebruiken), kunt u het algoritme bepalen en gebruiken om de originele hash te maken op een manier die vergelijkbaar is met de volgende:

<?php
if (substr($hashedPassword, 0, 4) == '$2y$' && strlen($hashedPassword) == 60) {
    echo 'Algorithm is Bcrypt';
    // the "cost" determines how strong this version of Bcrypt is
    preg_match('/\$2y\$(\d+)\$/', $hashedPassword, $matches);
    $cost = $matches[1];
    echo 'Bcrypt cost is '.$cost;
}
?>

Een wachtwoordhash maken

Maak wachtwoordhashes met behulp van password_hash() om de huidige standaard beste praktijkhash of sleutelafleiding te gebruiken. Op het moment van schrijven is de standaard bcrypt , wat betekent dat PASSWORD_DEFAULT dezelfde waarde bevat als PASSWORD_BCRYPT .

$options = [
    'cost' => 12,
];

$hashedPassword = password_hash($plaintextPassword, PASSWORD_DEFAULT, $options);

De derde parameter is niet verplicht .

De 'cost' waarde moet worden gekozen op basis van de hardware van uw productieserver. Als u dit verhoogt, wordt het wachtwoord duurder om te genereren. Hoe duurder het is om te genereren, hoe langer het duurt voordat iemand het probeert te kraken om het ook te genereren. De kosten moeten idealiter zo hoog mogelijk zijn, maar in de praktijk moeten deze zo worden ingesteld dat niet alles te veel wordt vertraagd. Ergens tussen 0,1 en 0,4 seconden zou goed zijn. Gebruik de standaardwaarde als u twijfelt.

5.5

Op PHP lager dan 5.5.0 zijn de password_* functies niet beschikbaar. U moet het compatibiliteitspakket gebruiken om die functies te vervangen. Merk op dat het compatibiliteitspakket PHP 5.3.7 of hoger vereist of een versie met de $2y fix achteraf (zoals RedHat biedt).

Als u deze niet kunt gebruiken, kunt u wachtwoordhashing implementeren met crypt() Omdat password_hash() is geïmplementeerd als een wrapper rond de crypt() -functie, hoeft u geen functionaliteit te verliezen.

// this is a simple implementation of a bcrypt hash otherwise compatible
// with `password_hash()`
// not guaranteed to maintain the same cryptographic strength of the full `password_hash()`
// implementation

// if `CRYPT_BLOWFISH` is 1, that means bcrypt (which uses blowfish) is available
// on your system
if (CRYPT_BLOWFISH == 1) {
    $salt = mcrypt_create_iv(16, MCRYPT_DEV_URANDOM);
    $salt = base64_encode($salt);
    // crypt uses a modified base64 variant
    $source = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
    $dest = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
    $salt = strtr(rtrim($salt, '='), $source, $dest);
    $salt = substr($salt, 0, 22);
    // `crypt()` determines which hashing algorithm to use by the form of the salt string
    // that is passed in
    $hashedPassword = crypt($plaintextPassword, '$2y$10$'.$salt.'$');
}

Zout voor wachtwoordhash

Ondanks de betrouwbaarheid van het crypt-algoritme is er nog steeds kwetsbaarheid voor regenboogtabellen . Dat is de reden, waarom het wordt aanbevolen om zout te gebruiken.

Een zout is iets dat aan het wachtwoord wordt toegevoegd voordat het wordt gehasht om de bronreeks uniek te maken. Gegeven twee identieke wachtwoorden, zullen de resulterende hashes ook uniek zijn, omdat hun zouten uniek zijn.

Een willekeurig zout is een van de belangrijkste onderdelen van uw wachtwoordbeveiliging. Dit betekent dat zelfs met een opzoektabel met bekende wachtwoordhash een aanvaller de wachtwoordhash van uw gebruiker niet kan vergelijken met de wachtwoordhash van de database, omdat een willekeurig zout is gebruikt. Gebruik altijd willekeurige en cryptografisch veilige zouten. Lees verder

Met het password_hash() bcrypt algoritme wordt gewoon bcrypt opgeslagen samen met de resulterende hash, wat betekent dat de hash kan worden overgedragen tussen verschillende systemen en platforms en toch kan worden vergeleken met het oorspronkelijke wachtwoord.

7.0

Zelfs wanneer dit wordt afgeraden, kunt u de salt gebruiken om uw eigen willekeurige zout te definiëren.

 $options = [
        'salt' => $salt, //see example below
 ];

Belangrijk Als u deze optie weglaat, wordt een willekeurig zout gegenereerd door wachtwoord_hash () voor elke wachtwoordhash. Dit is de beoogde bedieningsmodus.

7.0

De zoutoptie is verouderd vanaf PHP 7.0.0. Het heeft nu de voorkeur om eenvoudig het zout te gebruiken dat standaard wordt gegenereerd.

Een wachtwoord verifiëren tegen een hash

password_verify() is de ingebouwde functie (vanaf PHP 5.5) om de geldigheid van een wachtwoord tegen een bekende hash te verifiëren.

<?php
if (password_verify($plaintextPassword, $hashedPassword)) {
    echo 'Valid Password';
}
else {
    echo 'Invalid Password.';
}
?>

Alle ondersteunde hashing-algoritmen slaan informatie op die aangeeft welke hash in de hash zelf is gebruikt, dus het is niet nodig om aan te geven met welk algoritme u het wachtwoord voor de platte tekst codeert.

Als de functies wachtwoord_ * niet beschikbaar zijn op uw systeem (en u het compatibiliteitspakket dat in de onderstaande opmerkingen is gekoppeld, niet kunt gebruiken), kunt u wachtwoordverificatie uitvoeren met de functie crypt() . Houd er rekening mee dat bepaalde voorzorgsmaatregelen moeten worden genomen om te voorkomen timing aanvallen .

<?php
// not guaranteed to maintain the same cryptographic strength of the full `password_hash()`
// implementation
if (CRYPT_BLOWFISH == 1) {
    // `crypt()` discards all characters beyond the salt length, so we can pass in
    // the full hashed password
    $hashedCheck = crypt($plaintextPassword, $hashedPassword);

    // this a basic constant-time comparison based on the full implementation used
    // in `password_hash()`
    $status = 0;
    for ($i=0; $i<strlen($hashedCheck); $i++) {
        $status |= (ord($hashedCheck[$i]) ^ ord($hashedPassword[$i]));
    }

    if ($status === 0) {
        echo 'Valid Password';
    }
    else {
        echo 'Invalid Password';
    }
}
?>


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow