Posted By

mladoux on 08/15/12


Tagged

password security hash bcrypt


Versions (?)

BCrypt


 / Published in: PHP
 

URL: http://markladoux.com/

Only tested on PHP 5.4.4. Generates and verifies bcrypt hashes. Multibyte safe

  1. <?php
  2. /**
  3.  * BCrypt Library
  4.  *
  5.  * Password hashing library for HaKT Studios
  6.  *
  7.  * @author Mark LaDoux
  8.  * @copyright Copyright © 2012 Mark LaDoux
  9.  * @package HaKT Studios
  10.  * @subpackage Security
  11.  * @category Hashing
  12.  * @version 1.0.0
  13.  */
  14.  
  15. class BCrypt
  16. {
  17. /**
  18.   * Random hashing level
  19.   *
  20.   * @access protected
  21.   * @static int
  22.   */
  23. protected static $rounds;
  24.  
  25. /**
  26.   * Class Constructor
  27.   *
  28.   * @access public
  29.   * @return void
  30.   */
  31. public function __construct()
  32. {
  33. self::$rounds = mt_rand(8, 32);
  34. }
  35.  
  36. /**
  37.   * Generate a hash from string
  38.   *
  39.   * @access public
  40.   * @param string
  41.   * @return mixed returns hash string on success, or FALSE on failure
  42.   */
  43. public function generate($string)
  44. {
  45. // initialize salt
  46. $salt = sprintf('$2a$%02d$', self::$rounds);
  47.  
  48. // generate random bytes
  49. $bytes = '';
  50.  
  51. if( function_exists('openssl_random_pseudo_bytes') &&
  52. (mb_strtoupper(mb_substr(PHP_OS, 0, 3)) !== 'WIN'))
  53. {
  54. $bytes = openssl_random_pseudo_bytes(16);
  55. }
  56.  
  57. if( $bytes == '' &&
  58. is_readable('/dev/urandom') &&
  59. ($fh = @fopen('/dev/urandom', 'rb')) !== FALSE)
  60. {
  61. $bytes = fread($fh, 16);
  62. fclose($fh);
  63. }
  64.  
  65. if(mb_strlen($bytes, '8bit') < 16)
  66. {
  67. $bytes = '';
  68. $rstate = md5(microtime());
  69. if(function_exists('getmypid'))
  70. {
  71. $rstate .= getmypid();
  72. }
  73. }
  74.  
  75. $bytes = mb_substr($bytes, 0, 16, '8bit');
  76.  
  77. // encode bytes
  78. $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  79. $enc_bytes = '';
  80. $i = 0;
  81.  
  82. do
  83. {
  84. $c1 = ord($bytes[$i++]);
  85. $enc_bytes .= $itoa64[$c1 >> 2];
  86. $c1 = ($c1 & 0x03) << 4;
  87.  
  88. if($i >= 16)
  89. {
  90. $enc_bytes .= $itoa64[$c1];
  91. break;
  92. }
  93.  
  94. $c2 = ord($enc_bytes[$i++]);
  95. $c1 |= $c2 >> 6;
  96. $enc_bytes .= $itoa64[$c1];
  97. $enc_bytes .= $itoa64[$c2 & 0x3f];
  98. } while(1);
  99.  
  100. // create salt
  101. $salt .= $enc_bytes;
  102.  
  103. // hash password
  104. $hash = crypt($string, $salt);
  105.  
  106. // create output
  107. $output = (mb_strlen($hash) > 13) ? $hash : FALSE;
  108.  
  109. // return output
  110. return $output;
  111. }
  112.  
  113. /**
  114.   * Verify string against a hash
  115.   *
  116.   * @access public
  117.   * @param string $string
  118.   * @param string $hash
  119.   * @return bool
  120.   */
  121. public function verify($string, $hash)
  122. {
  123. $output = (crypt($string, $hash) == $hash) ? TRUE : FALSE;
  124. return $output;
  125. }
  126. }

Report this snippet  

You need to login to post a comment.