Skip to content.

Scott Arciszewski

Software, Privacy, Security, Innovation

Using scrypt in PHP-based Websites

Most newbie PHP developers suck at developing user authentication systems. When not storing passwords in plaintext, they just wing it with a simple hash function and hope it's good enough.

Instead of md5(), sha1(), or hash(), you should consider using scrypt, pbkdf2, or bcrypt.

Today, I'll go through the steps required to start using scrypt in your web applications. Installation is pretty easy if you have root permissions ;)

Installing Scrypt

Enter the following commands on your server in a Terminal window (or over SSH):

sudo -i
apt-get install php5-dev php-pear
pecl install scrypt
echo "extension=scrypt.so" > /etc/php5/mods-available/scrypt.ini
php5enmod scrypt

Next, restart apache/php5-fpm and you should be good to go.

Using Scrypt

Installing the PECL extension adds a PHP function called scrypt. Its function prototype is as follows:

function scrypt($password, $salt, $N, $r, $p, $outputKeyLength);

If you want a better understanding of what values to pass, check out the scrypt documentation on the Tarsnap website. If in doubt, set $r = 8 and $p = 1 and set $N to a sufficient power of 2 (i.e. 8192, 16384, 32768, 65536, etc.).

The author of the scrypt PECL extension offers an example wrapper class here; however, it uses mt_rand() for salt generation. A more attractive example would be to use mcrypt_create_iv() or openssl_random_pseudo_bytes() and then base64_encode() the result for storage.

So if you'd prefer, I forked their github repo and made my own changes here. You can also use your own library, but doing so could result in disaster; it would be better to have a trusted cryptographer write it for you.

Update: They have since corrected the salt generation code to use a CSPRNG, so their code is safe to use.

Using the aforementioned library, generating a hash is as simple as:

  $hash = Password::hash($yourPassword);

Verifying your hash is as simple as:

if(Password::check($_POST['password'], $storedPasswordHash)) {
    // Success
} else {
    // Failure
}

Security Considerations

Salts are not considered cryptographic secrets (since they are stored as plaintext with the password hashes). Using a stronger random number generator than mt_rand() might not be necessary; however, I beleive it is more prudent to do so when possible.

In Conclusion

When I set out to use scrypt for passwords, I thought it would be a much more daunting task. Fortunately, Dominic Black did a lot of the groundwork and there's basically no excuse to not use it for new systems that aren't already using pbkdf2 or bcrypt. Otherwise, it's time for an upgrade.

3 Comments on this Blog Post

Blog Archives Categories Latest Comments