Skip to content

Instantly share code, notes, and snippets.

@sitedyno
Created June 20, 2012 02:06
Show Gist options
  • Save sitedyno/2957740 to your computer and use it in GitHub Desktop.
Save sitedyno/2957740 to your computer and use it in GitHub Desktop.
<?php
class Bcrypt {
/**
* Standard DES encryption method
*
* @const STD_DES
*/
const STD_DES = 'CRYPT_STD_DES';
/**
* Extended DES encryption method
*
* @const EXT_DES
*/
const EXT_DES = 'CRYPT_EXT_DES';
/**
* MD5 encryption method
*
* @const MD5
*/
const MD5 = 'CRYPT_MD5';
/**
* BLOWFISH encryption method
*
* @const BLOWFISH
*/
const BLOWFISH = 'CRYPT_BLOWFISH';
/**
* SHA256 encryption method
*
* @const SHA256
*/
const SHA256 = 'CRYPT_SHA256';
/**
* SHA512 encryption method
*
* @const SHA512
*/
const SHA512 = 'CRYPT_SHA512';
/**
* Crypt settings.
*
* @var array
*/
public static $cryptSettings = array(
'cryptType' => self::BLOWFISH,
'cost' => 10,
);
/**
* Salt properties.
*
* @var array
*/
protected static $_saltProperties = array(
'saltFormat' => array(
self::STD_DES => '%s',
self::EXT_DES => '_%s%s',
self::MD5 => '$1$%s$',
self::BLOWFISH => '$2a$%s$%s$',
self::SHA256 => '$5$rounds=%s$%s$',
self::SHA512 => '$6$rounds=%s$%s$'
),
'saltLength' => array(
self::STD_DES => 2,
self::EXT_DES => 4,
self::MD5 => 12,
self::BLOWFISH => 22,
self::SHA256 => 16,
self::SHA512 => 16
),
'costLimits' => array(
self::EXT_DES => array(25, 16777215),
self::BLOWFISH => array(4, 31),
self::SHA256 => array(1000, 999999999),
self::SHA512 => array(1000, 999999999)
)
);
/**
* Generates a psuedo random salt suitable for use with php's crypt() function.
* The salt length should not exceed 27. The salt will be composed of
* [./0-9A-Za-z]{$length}.
*
* @param integer $length The length of the returned salt
* @return string The generated salt
*/
public static function salt($length = 22) {
return substr(str_replace('+', '.', base64_encode(sha1(uniqid(Configure::read('Security.salt'), true), true))), 0, $length);
}
/**
* One way encryption using php's crypt() function.
*
* ### Options that can be passed to $options.
*
* - cryptType - The encryption type to use for this function call.
* - cost - The cost to compute the hash. Keep in mind using a higher cost will
* slow down your system
*
* @param string $password The string to be encrypted.
* @param string $salt
* @param array $options Array of options to override default settings, see above.
*/
public static function crypt($password, $salt = false, $options = array()) {
$options = array_merge(self::$cryptSettings, $options, self::$_saltProperties);
extract($options);
if ($salt === false) {
if (isset($costLimits[$cryptType]) && ($cost < $costLimits[$cryptType][0] || $cost > $costLimits[$cryptType][1])) {
trigger_error(sprintf(
__d(
'cake_dev',
'When using %s you must specify a cost between %s and %s',
array(
$cryptType,
$costLimits[$cryptType][0],
$costLimits[$cryptType][1]
)
),
E_USER_WARNING
));
return '';
}
$vspArgs = array();
$salt = self::salt($saltLength[$cryptType]);
if ($cryptType === self::BLOWFISH) {
$bfCost = chr(ord('0') + $cost / 10);
$bfCost .= chr(ord('0') + $cost % 10);
$vspArgs[] = $bfCost;
}
if ($cryptType === self::SHA256 || $cryptType === self::SHA512) {
$vspArgs[] = $cost;
}
if ($cryptType === self::EXT_DES) {
$encode = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
$edCost = $encode[$cost & 0x3f];
$edCost .= $encode[($cost >> 6) & 0x3f];
$edCost .= $encode[($cost >> 12) & 0x3f];
$edCost .= $encode[($cost >> 18) & 0x3f];
$vspArgs[] = $edCost;
}
$vspArgs[] = $salt;
$salt = vsprintf($saltFormat[$cryptType], $vspArgs);
}
return crypt($password, $salt);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment