ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
APR1_MD5.php
Go to the documentation of this file.
1 <?php
2 
3 namespace WhiteHat101\Crypt;
4 
5 class APR1_MD5 {
6 
7  const BASE64_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
8  const APRMD5_ALPHABET = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
9 
10  // Source/References for core algorithm:
11  // http://www.cryptologie.net/article/126/bruteforce-apr1-hashes/
12  // http://svn.apache.org/viewvc/apr/apr-util/branches/1.3.x/crypto/apr_md5.c?view=co
13  // http://www.php.net/manual/en/function.crypt.php#73619
14  // http://httpd.apache.org/docs/2.2/misc/password_encryptions.html
15  // Wikipedia
16 
17  public static function hash($mdp, $salt = null) {
18  if (is_null($salt))
19  $salt = self::salt();
20  $salt = substr($salt, 0, 8);
21  $max = strlen($mdp);
22  $context = $mdp.'$apr1$'.$salt;
23  $binary = pack('H32', md5($mdp.$salt.$mdp));
24  for($i=$max; $i>0; $i-=16)
25  $context .= substr($binary, 0, min(16, $i));
26  for($i=$max; $i>0; $i>>=1)
27  $context .= ($i & 1) ? chr(0) : $mdp[0];
28  $binary = pack('H32', md5($context));
29  for($i=0; $i<1000; $i++) {
30  $new = ($i & 1) ? $mdp : $binary;
31  if($i % 3) $new .= $salt;
32  if($i % 7) $new .= $mdp;
33  $new .= ($i & 1) ? $binary : $mdp;
34  $binary = pack('H32', md5($new));
35  }
36  $hash = '';
37  for ($i = 0; $i < 5; $i++) {
38  $k = $i+6;
39  $j = $i+12;
40  if($j == 16) $j = 5;
41  $hash = $binary[$i].$binary[$k].$binary[$j].$hash;
42  }
43  $hash = chr(0).chr(0).$binary[11].$hash;
44  $hash = strtr(
45  strrev(substr(base64_encode($hash), 2)),
46  self::BASE64_ALPHABET,
47  self::APRMD5_ALPHABET
48  );
49  return '$apr1$'.$salt.'$'.$hash;
50  }
51 
52  // 8 character salts are the best. Don't encourage anything but the best.
53  public static function salt() {
54  $alphabet = self::APRMD5_ALPHABET;
55  $salt = '';
56  for($i=0; $i<8; $i++) {
57  $offset = hexdec(bin2hex(openssl_random_pseudo_bytes(1))) % 64;
58  $salt .= $alphabet[$offset];
59  }
60  return $salt;
61  }
62 
63  public static function check($plain, $hash) {
64  $parts = explode('$', $hash);
65  return self::hash($plain, $parts[2]) === $hash;
66  }
67 
68 }
static hash($mdp, $salt=null)
Definition: APR1_MD5.php:17
static check($plain, $hash)
Definition: APR1_MD5.php:63
$i
Definition: disco.tpl.php:19
hash(StreamInterface $stream, $algo, $rawOutput=false)
Calculate a hash of a Stream.
Definition: functions.php:406