Skip to content

Instantly share code, notes, and snippets.

@hinzundcode
Created August 2, 2012 14:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hinzundcode/3237572 to your computer and use it in GitHub Desktop.
Save hinzundcode/3237572 to your computer and use it in GitHub Desktop.
<?php
use schokocappucino\Nameless\User\PasswordEncoder\CryptBlowfishPasswordEncoder;
use schokocappucino\Nameless\User\PasswordEncoder\PlaintextPasswordEncoder;
$app['password_encoders'] = new \Pimple();
$app['password_encoders']['crypt_blowfish.cost'] = 10;
$app['password_encoders']['crypt_blowfish'] = $app['password_encoders']->share(function ($password_encoders) {
return new CryptBlowfishPasswordEncoder($password_encoders['crypt_blowfish.cost']);
});
$app['password_encoders']['plaintext'] = $app['password_encoders']->share(function ($password_encoders) {
return new PlaintextPasswordEncoder();
});
<?php
namespace schokocappucino\Nameless\User\PasswordEncoder;
class CryptBlowfishPasswordEncoder implements PasswordEncoderInterface {
protected $cost = 10;
public function __construct($cost) {
if ($cost < 4 || $cost > 31)
throw new Exception('Invalid bcrypt cost parameter specified: '.$cost);
$this->cost = $cost;
}
public function salt() {
if (function_exists('mcrypt_create_iv')) {
$buffer = mcrypt_create_iv(16, \MCRYPT_DEV_URANDOM);
if ($buffer) return substr(str_replace('+', '.', base64_encode($buffer)), 0, 22);
}
if (function_exists('openssl_random_pseudo_bytes')) {
$buffer = openssl_random_pseudo_bytes(16);
if ($buffer) return substr(str_replace('+', '.', base64_encode($buffer)), 0, 22);
}
$buffer = '';
for ($i = 0; $i < 16; $i++) {
$buffer .= chr(mt_rand(0, 255));
}
return substr(str_replace('+', '.', base64_encode($buffer)), 0, 22);
}
public function hash($password, $salt) {
$hash_format = sprintf('$2y$%02d$', $this->cost);
$hash = crypt($password, $hash_format.$salt);
return (!is_string($hash) || strlen($hash) < 13) ? false : $hash;
}
public function verify($password, $salt, $hash) {
$return = crypt($password, $hash);
if (!is_string($return) || strlen($return) != strlen($hash))
return false;
$status = 0;
for ($i = 0; $i < strlen($return); $i++) {
$status |= (ord($return[$i]) ^ ord($hash[$i]));
}
return $status === 0;
}
}
<?php
// update password hash if the user's password encoder isn't $app['user.password_encoder']
if ($user->passwordEncoder != $app['user.password_encoder'] && isset($app['password_encoders'][$app['user.password_encoder']])) {
$password_encoder = $app['password_encoders'][$app['user.password_encoder']];
$user->passwordEncoder = $app['user.password_encoder'];
$user->passwordSalt = $password_encoder->salt();
$user->passwordHash = $password_encoder->hash($data['password'], $user->passwordSalt);
$user->save();
}
<?php
namespace schokocappucino\Nameless\User\PasswordEncoder;
interface PasswordEncoderInterface {
public function salt();
public function hash($password, $salt);
public function verify($password, $salt, $hash);
}
<?php
namespace schokocappucino\Nameless\User\PasswordEncoder;
class PlaintextPasswordEncoder implements PasswordEncoderInterface {
public function salt() {
return '';
}
public function hash($password, $salt) {
return $password;
}
public function verify($password, $salt, $hash) {
return $password === $hash;
}
}
<?php
$user = $app['users']->create();
$user->username = $data['username'];
$user->passwordEncoder = $app['user.password_encoder'];
$user->passwordSalt = $app['password_encoders'][$user->passwordEncoder]->salt();
$user->passwordHash = $app['password_encoders'][$user->passwordEncoder]->hash($data['password'], $user->passwordSalt);
$app['em']->save($user);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment