Back-ported hash_pbkdf2() from PHP 5.5
Tuesday, January 22. 2013
PHP has been lacking properly implemented password-hash function. Many web-sites really would benefit from having such a thing available. Zend Framework -guys implemented that into their ZF2. Nice! But for us not running ZF2, doing 1000 hashes in a loop with PHP-code does not sound like a good idea.
Initially I thought that Mcrypt-project would implement PBKDF2 and PHP would gain the function that way. Apparently they're not interested either.
The good news comes from PHP-project. They implemented hash_pbkdf() into native PHP. Great! The problem is, that PHP 5.5.0 has not been released yet. I didn't want to wait and back-ported the function from PHP 5.5.0 source tree into my own 5.4.11.
For those wanting to build their own, the patch is here: php-5.4.11-pbkdf2.patch
The test from PHP manual page:
$hash = hash_pbkdf2("sha256", $password, $salt, 1, 20);
echo $hash . "\n";
Yields exactly correct result: 120fb6cffcf8b32c43e7
Doing only 1 round is very naive. The recommended minimum is 1000 and apparently 2000 is the way to go. I took Zend Framework's Zend\Crypt\Key\Derivation\Pbkdf2 as a reference and did 2000 rounds instead of 20. Both algoritms return exactly the same result, though they handle the length-parameter differently. ZF2 assumes bytes, but PHP's native version assumes hex-string length. But I did iron out the difference in my code.
The native version does 2000 rounds in 0.00674 seconds, and native PHP-version does that in 0.012470 seconds, so C-compiled binary is 100% faster.
My test code for native version:
<?php
$password = "password";
$salt = "salt";
$now = microtime(true);
$hash = hash_pbkdf2("sha256", $password, $salt, 2000, 20);
$dura = microtime(true) - $now;
echo $hash . "\n";
echo sprintf("%12.11F", $dura) . " seconds\n";
?>
My test code for Zend Framework 2 version:
<?php
require_once 'Hmac.php';
require_once 'Pbkdf2.php';
$password = "password";
$salt = "salt";
$now = microtime(true);
$hash = Zend\Crypt\Key\Derivation\Pbkdf2::calc("sha256", $password, $salt, 2000, 10);
$dura = microtime(true) - $now;
echo bin2hex($hash) . "\n";
echo sprintf("%12.11F", $dura) . " seconds\n";
?>
If you're site is not storing passwords properly, its about time to start now.
vim modelines
Tuesday, January 22. 2013
My weapon-of-choice in Linux CLI is vim. However, out-of-the-box it acts very stubbornly when editing files with modeline. The nice modelines seem to have zero effect. WTF!?
To my amazement, it appears that modelines are turned off as a default. It can be verified with a simple echo command from vim:
:echo &modeline
will yield 0 as an answer. So step 1 is to enable them in ~/.vimrc, if the file does not exist, create it. If it does exist, make sure that it contains following:
set modeline
Then confirm that echo will display 1 to indicate that modeline is enforced. What a great idea to not enable them! Nice going suckers!
To create your own modeline, put something like this into your file:
# vim: tabstop=4 shiftwidth=4 softtabstop=4 expandtab:
It reads:
- tabstop=4
- The width of a TAB is set to 4. Still it is a \t. It is just that vim will interpret it to be having width of 4.
- shiftwidth=4
- Indents will have a width of 4
- softtabstop=4
- Sets the number of columns for a TAB
- expandtab
- Expand TABs to spaces