bcrypt
ist ein Hashing-Algorithmus, der mit Hardware skalierbar ist (über eine konfigurierbare Anzahl von Runden). Die Langsamkeit und die mehrfachen Runden stellen sicher, dass ein Angreifer massive Mittel und Hardware einsetzen muss, um Ihre Passwörter knacken zu können. Fügen Sie dazu pro Passwort Salze hinzu (bcrypt
VERLANGT Salze) und Sie können sicher sein, dass ein Angriff praktisch unmöglich ist, es sei denn, es gibt entweder absurde Geldmittel oder Hardware.
bcrypt
verwendet den Eksblowfish-Algorithmus zum Hashen von Passwörtern. Während die Verschlüsselungsphase von Eksblowfish und Blowfish genau gleich sind, sorgt die Schlüsselplanungsphase von Eksblowfish dafür, dass ein späterer Zustand sowohl vom Salz als auch vom Schlüssel (Benutzerpasswort) abhängt und kein Zustand ohne Kenntnis von beidem vorberechnet werden kann. Aufgrund dieses Schlüsselunterschieds ist bcrypt
einseitiger Hash-Algorithmus. Sie können das Klartextpasswort nicht abrufen, ohne bereits das Salz, die Runden und den Schlüssel (Passwort) zu kennen. [Quelle]
Wie man bcrypt verwendet:
Mit PHP >= 5.5-DEV
Passwort-Hashing-Funktionen sind jetzt direkt in PHP >= 5.5 integriert. Sie können jetzt password_hash()
verwenden, um einen bcrypt
-Hash eines beliebigen Passworts zu erstellen:
11
];
echo password_hash('rasmuslerdorf', PASSWORD_BCRYPT, $options)."\n";
// $2y$11$6DP.V0nO7YI3iSki4qog6OQI5eiO6Jnjsqg7vdnb.JgGIsxniOn4C
Um ein vom Benutzer bereitgestelltes Passwort gegen einen vorhandenen Hash zu überprüfen, können Sie password_verify()
wie folgt verwenden:
``
Mit PHP >= 5.3.7, < 5.5-DEV (auch RedHat PHP >= 5.3.3)
Es gibt eine Kompatibilitätsbibliothek auf GitHub, die auf dem Quellcode der oben genannten Funktionen basiert, die ursprünglich in C geschrieben wurden und dieselbe Funktionalität bietet. Sobald die Kompatibilitätsbibliothek installiert ist, ist die Verwendung dieselbe wie oben (abzüglich der Kurzarray-Schreibweise, wenn Sie immer noch auf dem 5.3.x-Zweig sind).
Mit PHP < 5.3.7 (VERALTET)
Sie können die Funktion crypt()
verwenden, um bcrypt-Hashes von Eingabestrings zu generieren. Diese Klasse kann automatisch Salze generieren und vorhandene Hashes gegen eine Eingabe überprüfen. Wenn Sie eine PHP-Version höher oder gleich 5.3.7 verwenden, wird dringend empfohlen, die integrierte Funktion oder die Kompatibilitätsbibliothek zu verwenden. Dieses Alternative wird nur aus historischen Gründen bereitgestellt.
class Bcrypt{
private $rounds;
public function __construct($rounds = 12) {
if (CRYPT_BLOWFISH != 1) {
throw new Exception("bcrypt in dieser Installation nicht unterstützt. Siehe http://php.net/crypt");
}
$this->rounds = $rounds;
}
public function hash($input){
$hash = crypt($input, $this->getSalt());
if (strlen($hash) > 13)
return $hash;
return false;
}
public function verify($input, $existingHash){
$hash = crypt($input, $existingHash);
return $hash === $existingHash;
}
private function getSalt(){
$salt = sprintf('$2a$%02d$', $this->rounds);
$bytes = $this->getRandomBytes(16);
$salt .= $this->encodeBytes($bytes);
return $salt;
}
private $randomState;
private function getRandomBytes($count){
$bytes = '';
if (function_exists('openssl_random_pseudo_bytes') &&
(strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) { // OpenSSL ist langsam unter Windows
$bytes = openssl_random_pseudo_bytes($count);
}
if ($bytes === '' && is_readable('/dev/urandom') &&
($hRand = @fopen('/dev/urandom', 'rb')) !== FALSE) {
$bytes = fread($hRand, $count);
fclose($hRand);
}
if (strlen($bytes) < $count) {
$bytes = '';
if ($this->randomState === null) {
$this->randomState = microtime();
if (function_exists('getmypid')) {
$this->randomState .= getmypid();
}
}
for ($i = 0; $i < $count; $i += 16) {
$this->randomState = md5(microtime() . $this->randomState);
if (PHP_VERSION >= '5') {
$bytes .= md5($this->randomState, true);
} else {
$bytes .= pack('H*', md5($this->randomState));
}
}
$bytes = substr($bytes, 0, $count);
}
return $bytes;
}
private function encodeBytes($input){
// Der folgende Code stammt aus dem PHP Password Hashing Framework
$itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
$output = '';
$i = 0;
do {
$c1 = ord($input[$i++]);
$output .= $itoa64[$c1 >> 2];
$c1 = ($c1 & 0x03) << 4;
if ($i >= 16) {
$output .= $itoa64[$c1];
break;
}
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 4;
$output .= $itoa64[$c1];
$c1 = ($c2 & 0x0f) << 2;
$c2 = ord($input[$i++]);
$c1 |= $c2 >> 6;
$output .= $itoa64[$c1];
$output .= $itoa64[$c2 & 0x3f];
} while (true);
return $output;
}
}
Sie können diesen Code wie folgt verwenden:
$bcrypt = new Bcrypt(15);
$hash = $bcrypt->hash('password');
$isGood = $bcrypt->verify('password', $hash);
Alternativ können Sie auch das Portable PHP Hashing Framework verwenden.
``