Overview

Namespaces

  • None
  • PHP
  • Pry
    • Auth
      • Interfaces
    • Config
    • Controller
    • Date
    • Db
    • Feed
      • Abstracts
      • Writers
    • File
      • Decorator
    • Form
      • Element
    • Image
    • Log
      • Writer
    • Net
      • Exception
    • Session
    • Util
    • Validate
      • Validator
    • View

Classes

  • ACL
  • Auth
  • Bcrypt
  • Util
  • WithRole
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Pry Framework
  5:  *
  6:  * LICENSE
  7:  *
  8:  * This source file is subject to the new BSD license that is bundled
  9:  * with this package in the file LICENSE.txt.
 10:  * 
 11:  */
 12: 
 13: namespace Pry\Auth;
 14: 
 15: /**
 16:  * Classe implémentant l'algorithm bcrypt pour le cryptage de mot de passe.
 17:  * <code>
 18:  * $bcrypt = new Bcrypt(11);
 19:  * $hash = $bcrypt->hash('mypass');
 20:  * var_dump($bcrypt->check('mypass',$hash);
 21:  * </code>
 22:  * @package Auth
 23:  * @version 1.0
 24:  * @author Olivier ROGER <oroger.fr>
 25:  * @see http://en.wikipedia.org/wiki/Bcrypt
 26:  * @see http://stackoverflow.com/questions/4795385/how-do-you-use-bcrypt-for-hashing-passwords-in-php
 27:  */
 28: class Bcrypt
 29: {
 30:     /** Base du grain de sel blowfish */
 31: 
 32:     const SALTBASE = '$2a$';
 33: 
 34:     /** Logarithme base 2 du compteur d'itération */
 35:     private $iterations;
 36: 
 37:     /** Aléa pour le grain de sel */
 38:     private $random;
 39: 
 40:     /**
 41:      * Initialise le cryptage
 42:      * @param int $rounds Nombre d'itération pour l'algo de hashage entre 4 et 31. 
 43:      * Plus ce paramètre est élevé plus le temps de hashage sera long. 12 par défaut
 44:      * @throws RuntimeException Si le cryptage BlowFish n'est pas supporté sur l'installation
 45:      * @throws InvalidArgumentException Le paramètres n'est pas compris entre 4 et 31.
 46:      */
 47:     public function __construct($rounds = 12)
 48:     {
 49:         if (CRYPT_BLOWFISH != 1)
 50:             throw new \RuntimeException('Blowfish is not available on your system, it is required for bcrypt');
 51: 
 52:         if ($rounds < 4 || $rounds > 31)
 53:             throw new \InvalidArgumentException(' The number of rounds have to be between 4 and 31');
 54: 
 55:         $this->iterations = $rounds;
 56:         $this->random     = microtime();
 57: 
 58:         if (function_exists('getmypid'))
 59:             $this->random .= getmypid();
 60:     }
 61: 
 62:     /**
 63:      * Hash la chaine donnée
 64:      * @param string $str Chaine en clair
 65:      * @return string Un hash de la chaine de 60 caractères
 66:      * @throws type 
 67:      */
 68:     public function hash($str)
 69:     {
 70:         $hash = crypt($str, $this->generateSalt());
 71:         if (strlen($hash) != 60)
 72:             throw \LengthException('Hash is ' . strlen($hash) . ' characters long , somethng went wrong');
 73: 
 74:         return $hash;
 75:     }
 76: 
 77:     /**
 78:      * Vérifie une chaine avec un hash
 79:      * @param string $str Chaine en claire
 80:      * @param string $hashedStr Un hash
 81:      * @return boolean True si les deux correspondent , false sinon 
 82:      */
 83:     public static function check($str, $hashedStr)
 84:     {
 85:         $hash = crypt($str, $hashedStr);
 86:         return $hash === $hashedStr;
 87:     }
 88: 
 89:     /**
 90:      * Génération d'un grain de sel pour le hashage
 91:      * @return string 
 92:      */
 93:     private function generateSalt()
 94:     {
 95:         // Salt se forme aec : $2a$/2 digits/$/22 charactères parmis [./0-9a-Z]
 96:         $salt  = Bcrypt::SALTBASE . $this->iterations . '$';
 97:         $bytes = $this->getRandomBytes(16);
 98:         $salt .= $this->getBlowfishSalt($bytes);
 99: 
100:         return $salt;
101:     }
102: 
103:     /**
104:      * Génération de bytes aléatoires
105:      * @param int $size Nombre de byte à générer
106:      * @return bytes 
107:      */
108:     private function getRandomBytes($size)
109:     {
110:         $bytes = '';
111: 
112:         // /dev/urandom est la meilleur source d'aléa , on test sa disponibilité : 
113:         if (is_readable('/dev/urandom'))
114:         {
115:             $handle = @fopen('/dev/urandom', 'rb');
116:             if ($handle)
117:             {
118:                 $bytes = fread($handle, $size);
119:             }
120:         }
121: 
122:         // Si pas de dev/urandom on essai avec openssl
123:         if ($bytes === '' && function_exists('openssl_random_pseudo_bytes'))
124:             $bytes = openssl_random_pseudo_bytes($size);
125: 
126:         //Si aucun des procédés dispo ou si la génération n'as pas la bonne taille
127:         if (strlen($bytes) < $size)
128:         {
129:             $bytes = '';
130: 
131:             $this->random = md5(microtime() . $this->random);
132:             $bytes .= md5($this->random, true); // Retour en byte et non string
133: 
134:             $bytes = substr($bytes, 0, $size);
135:         }
136: 
137:         return $bytes;
138:     }
139: 
140:     /**
141:      * Transformation des bytes générés.
142:      * Code original par phpass
143:      * @see http://www.openwall.com/phpass/
144:      * @param rawbytes $input
145:      * @return string 
146:      */
147:     private function getBlowfishSalt($input)
148:     {
149:         $itoa64 = './ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
150:         $output = '';
151:         $i      = 0;
152:         do {
153:             $c1 = ord($input[$i++]);
154:             $output .= $itoa64[$c1 >> 2];
155:             $c1 = ($c1 & 0x03) << 4;
156:             if ($i >= 16)
157:             {
158:                 $output .= $itoa64[$c1];
159:                 break;
160:             }
161: 
162:             $c2 = ord($input[$i++]);
163:             $c1 |= $c2 >> 4;
164:             $output .= $itoa64[$c1];
165:             $c1 = ($c2 & 0x0f) << 2;
166: 
167:             $c2 = ord($input[$i++]);
168:             $c1 |= $c2 >> 6;
169:             $output .= $itoa64[$c1];
170:             $output .= $itoa64[$c2 & 0x3f];
171:         } while (1);
172: 
173:         return $output;
174:     }
175: 
176: }
177: 
178: ?>
179: 
Pry API documentation generated by ApiGen 2.8.0