function check_password($password, $correctHash) { $params = explode(":", $correctHash); if (count($params) < HASH_SECTIONS) { return false; } return slow_equals($params[HASH_INDEX], hash(SHA256_HASH_ALGORITHM, $password . $params[SALT_INDEX])); }
function validate_password($password, $good_hash) { $params = explode(":", $good_hash); if (count($params) < HASH_SECTIONS) { return false; } $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]); return slow_equals($pbkdf2, pbkdf2($params[HASH_ALGORITHM_INDEX], $password, $params[HASH_SALT_INDEX], (int) $params[HASH_ITERATION_INDEX], strlen($pbkdf2), true)); }
function cpg_password_validate($password, $correct_hash) { if (is_array($correct_hash)) { $params = array(HASH_ALGORITHM_INDEX => $correct_hash['user_password_hash_algorithm'], HASH_ITERATION_INDEX => $correct_hash['user_password_iterations'], HASH_SALT_INDEX => $correct_hash['user_password_salt'], HASH_PBKDF2_INDEX => $correct_hash['user_password']); } else { $params = explode(":", $correct_hash); } if (count($params) < HASH_SECTIONS) { return false; } $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]); return slow_equals($pbkdf2, pbkdf2($params[HASH_ALGORITHM_INDEX], $password, $params[HASH_SALT_INDEX], (int) $params[HASH_ITERATION_INDEX], strlen($pbkdf2), true)); }
function processPasteDelete($pasteid, $deletetoken) { if (preg_match('/\\A[a-f\\d]{16}\\z/', $pasteid)) { $filename = dataid2path($pasteid) . $pasteid; if (!is_file($filename)) { return array('', 'Paste does not exist, has expired or has been deleted.', ''); } } else { return array('', 'Invalid data', ''); } if (!slow_equals($deletetoken, hash_hmac('sha1', $pasteid, getServerSalt()))) { return array('', 'Wrong deletion token. Paste was not deleted.', ''); } // Paste exists and deletion token is valid: Delete the paste. deletePaste($pasteid); return array('', '', 'Paste was properly deleted.'); }
/** * Validate a string based on it's hash * * */ public function validate_hash($string, $correct_hash) { $params = explode(":", $correct_hash); if (count($params) < $this->hash_sections) { return false; } $pbkdf2 = base64_decode($params[$this->hash_pbkdf2_index]); return slow_equals($pbkdf2, $this->pbkdf2($params[$this->hash_algorithm_index], $string, $params[$this->hash_salt_index], (int) $params[$this->hash_iteration_index], strlen($pbkdf2), true)); }
echo "FAIL: [{$msg}]\n"; } } // The following test vectors were taken from RFC 6070. // https://www.ietf.org/rfc/rfc6070.txt $pbkdf2_vectors = array(array('algorithm' => 'sha1', 'password' => "password", 'salt' => "salt", 'iterations' => 1, 'keylength' => 20, 'output' => "0c60c80f961f0e71f3a9b524af6012062fe037a6"), array('algorithm' => 'sha1', 'password' => "password", 'salt' => "salt", 'iterations' => 2, 'keylength' => 20, 'output' => "ea6c014dc72d6f8ccd1ed92ace1d41f0d8de8957"), array('algorithm' => 'sha1', 'password' => "password", 'salt' => "salt", 'iterations' => 4096, 'keylength' => 20, 'output' => "4b007901b765489abead49d926f721d065a429c1"), array('algorithm' => 'sha1', 'password' => "passwordPASSWORDpassword", 'salt' => "saltSALTsaltSALTsaltSALTsaltSALTsalt", 'iterations' => 4096, 'keylength' => 25, 'output' => "3d2eec4fe41c849b80c8d83662c0e44a8b291a964cf2f07038"), array('algorithm' => 'sha1', 'password' => "password", 'salt' => "salt", 'iterations' => 4096, 'keylength' => 16, 'output' => "56fa6aa75548099dcc37d7f03425e0c3")); foreach ($pbkdf2_vectors as $test) { $realOut = pbkdf2($test['algorithm'], $test['password'], $test['salt'], $test['iterations'], $test['keylength'], false); assert_true($realOut === $test['output'], "PBKDF2 vector"); } $good_hash = create_hash("foobar"); assert_true(validate_password("foobar", $good_hash), "Correct password"); assert_true(validate_password("foobar2", $good_hash) === false, "Wrong password"); $h1 = explode(":", create_hash("")); $h2 = explode(":", create_hash("")); assert_true($h1[HASH_PBKDF2_INDEX] != $h2[HASH_PBKDF2_INDEX], "Different hashes"); assert_true($h1[HASH_SALT_INDEX] != $h2[HASH_SALT_INDEX], "Different salts"); assert_true(slow_equals("", ""), "Slow equals empty string"); assert_true(slow_equals("abcdef", "abcdef"), "Slow equals normal string"); assert_true(slow_equals("aaaaaaaaaa", "aaaaaaaaab") === false, "Slow equals different"); assert_true(slow_equals("aa", "a") === false, "Slow equals different length 1"); assert_true(slow_equals("a", "aa") === false, "Slow equals different length 2"); echo "Example hash: {$good_hash}\n"; // benchmark for ($i = 0; $i < 25; $i++) { $count = pow(2, $i); $start = microtime(true); $hash = pbkdf2("sha256", "password", "salt", $count, 32); $time = microtime(true) - $start; printf("%10d iterations: %f seconds\n", $count, $time); }
function login() { $conn = connexion_db(); if (check_email($_POST["login_email"], $conn) == 1) { //Le compte de cette adresse email existe //Recuperation du hash du mot de passe et le salt utilisateur $query = "SELECT utilisateur_password, utilisateur_salt, utilisateur_id FROM utilisateurs.utilisateur WHERE utilisateur_email = \$1;"; $result = pg_query_params($conn, $query, array($_POST['login_email'])); $row = pg_fetch_row($result); $user_valid_hash = pg_unescape_bytea($row[0]); $user_salt = pg_unescape_bytea($row[1]); $user_id = $row[2]; //Creation du hash afin de comparer les mots de passe $hash = hash("sha256", $user_salt . $_POST['password']); if (slow_equals($user_valid_hash, $hash)) { //Authentification réussie echo "<p>" . AUTHENTIFICATION_SUCCESS . "</p>"; //Génération d'un nombre aléatoire conservé par le client $salt = base64_encode(openssl_random_pseudo_bytes(512)); //Utilisation de l'adresse IP pour éviter les vols de cookie $ip = $_SERVER['REMOTE_ADDR']; $user_record = hash('sha256', $salt . $ip); $query = "INSERT INTO utilisateurs.rememberme (hashkey,user_id) VALUES (\$1, \$2)"; pg_query_params($conn, $query, array($user_record, $user_id)); //Le cookie expire au bout d'une semaine $expiration = time() + 3600 * 24 * 7; setcookie("user_id", $salt, $expiration); $_SESSION['connexion'] = true; } else { //Authentification échouée echo "<p>" . AUTHENTIFICATION_FAILURE . "</p>"; } } else { echo "<p>" . ERROR_LOGIN . "</p>"; } pg_close(); }