Revision #10                                    has been created by 
 samdark                                    on Mar 29, 2013, 10:20:24 AM with the memo:
                                
                                
                                    trying to fix github link                                
                                                                    « previous (#3)                                                                                                    next (#11) »                                                            
                            Changes
                            
    Title
    unchanged
    Use crypt() for password storage
    Category
    unchanged
    Tutorials
    Yii version
    unchanged
    
    Tags
    unchanged
    Authentication, security, password, hash, hashing
    Content
    changed
    Storing passwords in web apps
----
> There is now a `CPasswordHelper` class in `system.utils` <a href="https://github.com/yiisoft/yii/blob/master/framework/utils/CPasswordHelper.php">at GitHub</a> 
 
> that provides an API to simplify the use of `crypt()` for password storage. 
 
> While this wiki article remains valid, it will in due course be rewritten 
 
> to refer to the new class as well as explain how it works.
 
There are many tutorials and examples that show storage of passwords in a table.
Often the methods used are substandard and very easy to crack. There are many web pages and tutorials that show how to do it wrong.[...]
```php
crypt('EgzamplPassword', '$2a$10$1qAz2wSx3eDc4rFv5tGb5t')
	    >> '$2a$10$1qAz2wSx3eDc4rFv5tGb5e4jVuld5/KF2Kpy.B8D2XoC031sReFGi'
```[...]
```php
crypt('EgzamplPassword', '$2a$10$1qAz2wSx3eDc4rFv5tGb5t12345678901234567890')
	    >> '$2a$10$1qAz2wSx3eDc4rFv5tGb5e4jVuld5/KF2Kpy.B8D2XoC031sReFGi'
crypt('EgzamplPassword', '$2a$10$1qAz2wSx3eDc4rFv5tGb5t$2a$10$1qAz2wSx3eDc4rFv5tGb5t')
	    >> '$2a$10$1qAz2wSx3eDc4rFv5tGb5e4jVuld5/KF2Kpy.B8D2XoC031sReFGi'
```[...]
```php
crypt('EgzamplPassword', '$2a$10$1qAz2wSx3eDc4rFv5tGb5e4jVuld5/KF2Kpy.B8D2XoC031sReFGi')
	    >> '$2a$10$1qAz2wSx3eDc4rFv5tGb5e4jVuld5/KF2Kpy.B8D2XoC031sReFGi'
```[...]
**Validate password against a stored hash**
 
```php 
$hash === crypt($password, $hash)
 
```Compare the strings `$hash` and `crypt($password, $hash)`.
 
 
**NOTE:** We should use a constant-time string comparison algorithm to defeat 
 
the possibility of 
 
[timing attacks](http://blog.astrumfutura.com/2010/10/nanosecond-scale-remote-timing-attacks-on-php-applications-time-to-take-them-seriously/)
 
learning the result of validation. See below for an example.[...]
}
    $rand = array();
    for ($i = 0; $i < 8; ++$i
 += 1) {
        $rand[] = pack('S', mt_rand(0, 0xffff));
    }[...]
[sql]
create table user (
	    id int not null auto_increment primary key,
	    username varchar(255) not null,
	    password_hash char(64) not null,
	    unique key (email)
)
~~~[...]
```php
if ($password_hash === crypt($form->password, $record->passwordHash))
	    // password is correct
else
	    // password is wrong
```[...]
```
## Constant-time string comparison.
 
 
This function is based on 
 
[this](http://codereview.stackexchange.com/questions/13512/constant-time-string-comparision-in-php-to-prevent-timing-attacks) 
 
and 
 
[this](https://github.com/ircmaxell/password_compat/blob/master/lib/password.php).
 
 
 
```php 
function same($a, $b) {
 
    /**
 
     * @see http://codereview.stackexchange.com/questions/13512 
 
     */
 
    if (!is_string($a) || !is_string($b)) {
 
        return false;
 
    }
 
    $mb = function_exists('mb_strlen');
 
    $length = $mb ? mb_strlen($a, '8bit') : strlen($a);
 
    if ($length !== ($mb ? mb_strlen($b, '8bit') : strlen($b))) {
 
        return false;
 
    }
 
    $check = 0;
 
    for ($i = 0; $i < $length; $i += 1) {
 
        $check |= (ord($a[$i]) ^ ord($b[$i]));
 
    }
 
    return $check === 0;
 
}
 
```
 
 
 
## Availability of `crypt()`'s Blowfish option
The `crypt()` function has ben part of PHP for a long time but not all PHP installations[...]
move to a host with an up-to-date PHP.
Be careful of slow hash function implementations in PHP. The important thing is that the hash takes a lot of compute time *on the attackers equipment* and takes the minimum possible on yours. A hash implemented in PHP puts you at a disadvantage relative to the attacker. For example, imagine you iterate SHA-1 in in PHP for one second on a Micro instance on Amazon EC2 while the attacker has the same algorithm optimized to run on $5k's worth of modern GPUs. I don't know how many orders of magnitude faster the attacker's algorithm is than yours but I think its enough so that you should feel unsafe with such an implementation.