Validating Leaked Passwords with k-Anonymity using PHP

These days you can check if passwords are already breached in the pwnedpasswords.com database. You can just add this function to your php page or functions file.

It uses k-Anonymity and so only sends the first 5 characters of the hash and will received a list of compromised hashes. It will compare the hashed password on your server with the compromised hashes received from the API. On this you can act to advise a different password or maybe even let the user set a non-compromised password!

Make sure you install and enable the PHP-CURL module for Apache HTTPd

You can use the value returned via: $password_check_result
You can also adjust the returned output at:
if ($hitcounter > 0) {
echo “
Password is breached!“;
} else {
echo ‘
No hits found \o/‘;
}

Load the function in your php code and call it using:
password_check(“MySecretPassword“);
Where you can set the password to the user input.

<?php
 function password_check($password_check_input) {
    // Encrypt your password and uppercase all chars
    $sha1_password = strtoupper(sha1($password_check_input));
    // Trim to the first 5 characters of the hash
    $sha1_password_short = substr($sha1_password, 0, 5);

    // Fetch hash list
    $curl = curl_init();

            curl_setopt_array($curl, array(
                    CURLOPT_URL => "https://api.pwnedpasswords.com/range/$sha1_password_short",
                    CURLOPT_RETURNTRANSFER => true,
                    CURLOPT_ENCODING => "",
                    CURLOPT_MAXREDIRS => 10,
                    CURLOPT_TIMEOUT => 30,
                    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                    CURLOPT_CUSTOMREQUEST => "GET",
                    CURLOPT_HTTPHEADER => array(
                            "content-type: text/plain"
                    ),
            ));

    $response = curl_exec($curl);
    $err = curl_error($curl);

    // Put reponse into an array
    $lines = explode(PHP_EOL, $response);

    // Set hitcounter to ZERO
    $hitcounter=0;

    // Loop through all lines
    foreach ($lines as $line => $row) {
            // Join the 5 sha1 chars with the result
            $row = $sha1_password_short . $row;
            // Break output
            $row = explode(':', $row);
            // Set hash as row (part zero of the explode)
            $row = $row[0];

            // Check if the hash matches your encrypted password
            if ($row == $sha1_password) {
                    $hitcounter++;
            }
    }

    curl_close($curl);

    if ($err) {
            echo "cURL Error: $err";
    }

    if ($hitcounter > 0) {
            echo "Password is breached!";
    } else {
            echo 'No hits found \o/';
    }

    return $password_check_result;
}

Requirements:
– php module: php-curl

Was this post helpful?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.