Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit testing with hashed passwords

Right now I'm using the Zend Framework and messing around with that and phpunit. Here is my dilemma.

When I create a user I hash the password in the user table. I add two salts, a static one from the application and one that is randomly generated. I use the database SHA function and then UNHEX that to store the password in a binary column. In order to tell the database how to hash the password I use a Zend_Db_Expr like so :

protected function _createPasswordDbExpression( $password )
{

    $quoted = $this->getDbTable()->getAdapter()->quoteInto( 'UNHEX( SHA1( ? ) )', $password );
    $binaryPassword = new Zend_Db_Expr( $quoted );

    return $binaryPassword;
}

Up till now I've been using xml datasets to specify the expected results but now, with the hashed passwords, I don't know what to do.

I see a solution to this but there has to be a better way.

I could prehash a password, or passwords, and only use that during my testing and in my xml files.

Is there any other solution that might be better and more testable?

I don't know exactly how this binary column would affect things when phpunit tries to insert a "hashed" password directly.

like image 999
Jerry Saravia Avatar asked Feb 24 '23 15:02

Jerry Saravia


1 Answers

First off, never do that. Anyone with access to the database query history can see the raw passwords (they will be stored in the binary logs). Instead, hash them in the application so that the raw passwords are destroyed. By doing that, your database functionality just becomes a value store rather than something that needs unit testing.

Once you make it a PHP function, it's trivial to unit test (simply use any one of the number of the standard test vectors to ensure it was hashed correctly.

However, I would highly suggest using a salt and a derivation function for storing the password securely. You can see why in this answer. And as far as the exact algorithm, I'd suggest implementing PBKDF2. I have a PHP implementation that you could reverse engineer if you'd like here (the library is not production ready yet, but that algorithm is).

Finally, I'd suggest using one of the SHA2 algorithms instead of SHA1 (either SHA256 or SHA512 should suffice well). It's more collision resistant, and tends to be seen as being significantly stronger...

like image 107
ircmaxell Avatar answered Mar 29 '23 19:03

ircmaxell