Skip to content
This repository has been archived by the owner on Jan 8, 2020. It is now read-only.

Commit

Permalink
Merge branch 'feature/7141' into develop
Browse files Browse the repository at this point in the history
Close #7141
  • Loading branch information
weierophinney committed Mar 12, 2015
2 parents f4fa9cc + 86b9efb commit f1d8a39
Show file tree
Hide file tree
Showing 4 changed files with 179 additions and 8 deletions.
9 changes: 5 additions & 4 deletions library/Zend/Crypt/Password/Apache.php
Expand Up @@ -11,6 +11,7 @@

use Traversable;
use Zend\Math\Rand;
use Zend\Crypt\Utils;

/**
* Apache password authentication
Expand Down Expand Up @@ -126,7 +127,7 @@ public function verify($password, $hash)
{
if (substr($hash, 0, 5) === '{SHA}') {
$hash2 = '{SHA}' . base64_encode(sha1($password, true));
return ($hash === $hash2);
return Utils::compareStrings($hash, $hash2);
}
if (substr($hash, 0, 6) === '$apr1$') {
$token = explode('$', $hash);
Expand All @@ -136,7 +137,7 @@ public function verify($password, $hash)
);
}
$hash2 = $this->apr1Md5($password, $token[2]);
return ($hash === $hash2);
return Utils::compareStrings($hash, $hash2);
}
if (strlen($hash) > 13) { // digest
if (empty($this->userName) || empty($this->authName)) {
Expand All @@ -145,9 +146,9 @@ public function verify($password, $hash)
);
}
$hash2 = md5($this->userName . ':' . $this->authName . ':' .$password);
return ($hash === $hash2);
return Utils::compareStrings($hash, $hash2);
}
return (crypt($password, $hash) === $hash);
return Utils::compareStrings($hash, crypt($password, $hash));
}

/**
Expand Down
6 changes: 2 additions & 4 deletions library/Zend/Crypt/Password/Bcrypt.php
Expand Up @@ -12,6 +12,7 @@
use Traversable;
use Zend\Math\Rand;
use Zend\Stdlib\ArrayUtils;
use Zend\Crypt\Utils;

/**
* Bcrypt algorithm using crypt() function of PHP
Expand Down Expand Up @@ -101,10 +102,7 @@ public function create($password)
public function verify($password, $hash)
{
$result = crypt($password, $hash);
if ($result === $hash) {
return true;
}
return false;
return Utils::compareStrings($hash, $result);
}

/**
Expand Down
45 changes: 45 additions & 0 deletions library/Zend/Crypt/Password/BcryptSha.php
@@ -0,0 +1,45 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace Zend\Crypt\Password;

use Zend\Crypt\Hash;

/**
* Bcrypt algorithm using crypt() function of PHP with password
* hashed using SHA2 to allow for passwords >72 characters.
*/
class BcryptSha extends Bcrypt
{

/**
* BcryptSha
*
* @param string $password
* @throws Exception\RuntimeException
* @return string
*/
public function create($password)
{
return parent::create(Hash::compute('sha256', $password));
}

/**
* Verify if a password is correct against a hash value
*
* @param string $password
* @param string $hash
* @throws Exception\RuntimeException when the hash is unable to be processed
* @return bool
*/
public function verify($password, $hash)
{
return parent::verify(Hash::compute('sha256', $password), $hash);
}
}
127 changes: 127 additions & 0 deletions tests/ZendTest/Crypt/Password/BcryptShaTest.php
@@ -0,0 +1,127 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
*/

namespace ZendTest\Crypt\Password;

use Zend\Crypt\Password\Bcrypt;
use Zend\Crypt\Password\BcryptSha;
use Zend\Config\Config;
use Zend\Crypt\Password\Exception;

/**
* @group Zend_Crypt
*/
class BcryptShaTest extends \PHPUnit_Framework_TestCase
{
/** @var Bcrypt */
private $bcrypt;
/** @var string */
private $salt;
/** @var string */
private $bcryptPassword;
/** @var string */
private $password;

public function setUp()
{
$this->bcrypt = new BcryptSha();
$this->salt = '1234567890123456';
$this->password = 'test';
$this->prefix = '$2y$';

$this->bcryptPassword = $this->prefix . '10$MTIzNDU2Nzg5MDEyMzQ1NeqZGfIabq2.v6vX10KI4/z0pMoIoDyVa';
}

public function testConstructByOptions()
{
$options = array(
'cost' => '15',
'salt' => $this->salt
);
$bcrypt = new BcryptSha($options);
$this->assertTrue($bcrypt instanceof BcryptSha);
$this->assertEquals('15', $bcrypt->getCost());
$this->assertEquals($this->salt, $bcrypt->getSalt());
}

public function testConstructByConfig()
{
$options = array(
'cost' => '15',
'salt' => $this->salt
);
$config = new Config($options);
$bcrypt = new BcryptSha($config);
$this->assertTrue($bcrypt instanceof BcryptSha);
$this->assertEquals('15', $bcrypt->getCost());
$this->assertEquals($this->salt, $bcrypt->getSalt());
}

public function testWrongConstruct()
{
$this->setExpectedException('Zend\Crypt\Password\Exception\InvalidArgumentException',
'The options parameter must be an array or a Traversable');
$bcrypt = new BcryptSha('test');
}

public function testSetCost()
{
$this->bcrypt->setCost('16');
$this->assertEquals('16', $this->bcrypt->getCost());
}

public function testSetWrongCost()
{
$this->setExpectedException('Zend\Crypt\Password\Exception\InvalidArgumentException',
'The cost parameter of bcrypt must be in range 04-31');
$this->bcrypt->setCost('3');
}

public function testSetSalt()
{
$this->bcrypt->setSalt($this->salt);
$this->assertEquals($this->salt, $this->bcrypt->getSalt());
}

public function testSetSmallSalt()
{
$this->setExpectedException('Zend\Crypt\Password\Exception\InvalidArgumentException',
'The length of the salt must be at least ' . Bcrypt::MIN_SALT_SIZE . ' bytes');
$this->bcrypt->setSalt('small salt');
}

public function testCreateWithRandomSalt()
{
$password = $this->bcrypt->create('test');
$this->assertTrue(!empty($password));
$this->assertTrue(strlen($password) === 60);
}

public function testCreateWithSalt()
{
$this->bcrypt->setSalt($this->salt);
$password = $this->bcrypt->create($this->password);
$this->assertEquals($password, $this->bcryptPassword);
}

public function testVerify()
{
$this->assertTrue($this->bcrypt->verify($this->password, $this->bcryptPassword));
$this->assertFalse($this->bcrypt->verify(substr($this->password, -1), $this->bcryptPassword));
}

public function testPasswordWith8bitCharacter()
{
$password = 'test' . chr(128);
$this->bcrypt->setSalt($this->salt);

$this->assertEquals('$2y$10$MTIzNDU2Nzg5MDEyMzQ1NetiAf47gp.MSGw.8x1/hESvXYfMep1em',
$this->bcrypt->create($password));
}
}

0 comments on commit f1d8a39

Please sign in to comment.