forked from joomla/joomla-platform
/
simple.php
148 lines (128 loc) · 3.18 KB
/
simple.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
<?php
/**
* @package Joomla.Platform
* @subpackage Crypt
*
* @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE
*/
defined('JPATH_PLATFORM') or die;
/**
* Joomla Platform Password Crypter
*
* @package Joomla.Platform
* @subpackage Crypt
* @since 12.2
*/
class JCryptPasswordSimple implements JCryptPassword
{
/**
* @var integer The cost parameter for hashing algorithms.
* @since 12.2
*/
protected $cost = 10;
/**
* Creates a password hash
*
* @param string $password The password to hash.
* @param string $type The hash type.
*
* @return string The hashed password.
*
* @since 12.2
*/
public function create($password, $type = JCryptPassword::BLOWFISH)
{
switch ($type)
{
case JCryptPassword::BLOWFISH:
$salt = $this->getSalt(22);
if (version_compare(PHP_VERSION, '5.3.7') >= 0)
{
$prefix = '$2y$';
}
else
{
$prefix = '$2a$';
}
$salt = $prefix . str_pad($this->cost, 2, '0', STR_PAD_LEFT) . '$' . $this->getSalt(22);
return crypt($password, $salt);
case JCryptPassword::MD5:
$salt = $this->getSalt(12);
$salt = '$1$' . $salt;
return crypt($password, $salt);
case JCryptPassword::JOOMLA:
$salt = $this->getSalt(32);
return md5($password . $salt) . ':' . $salt;
default:
throw new InvalidArgumentException(sprintf('Hash type %s is not supported', $type));
break;
}
}
/**
* Sets the cost parameter for the generated hash for algorithms that use a cost factor.
*
* @param integer $cost The new cost value.
*
* @return void
*
* @since 12.2
*/
public function setCost($cost)
{
$this->cost = $cost;
}
/**
* Generates a salt of specified length. The salt consists of characters in the set [./0-9A-Za-z].
*
* @param integer $length The number of characters to return.
*
* @return string The string of random characters.
*
* @since 12.2
*/
protected function getSalt($length)
{
$bytes = ceil($length * 6 / 8);
$randomData = str_replace('+', '.', base64_encode(JCrypt::getRandomBytes($bytes)));
return substr($randomData, 0, $length);
}
/**
* Verifies a password hash
*
* @param string $password The password to verify.
* @param string $hash The password hash to check.
*
* @return boolean True if the password is valid, false otherwise.
*
* @since 12.2
*/
public function verify($password, $hash)
{
// Check if the hash is a blowfish hash.
if (substr($hash, 0, 4) == '$2a$' || substr($hash, 0, 4) == '$2y$')
{
if (version_compare(PHP_VERSION, '5.3.7') >= 0)
{
$prefix = '$2y$';
}
else
{
$prefix = '$2a$';
}
$hash = $prefix . substr($hash, 4);
return (crypt($password, $hash) === $hash);
}
// Check if the hash is an MD5 hash.
if (substr($hash, 0, 3) == '$1$')
{
return (crypt($password, $hash) === $hash);
}
// Check if the hash is a Joomla hash.
if (preg_match('#[a-z0-9]{32}:[A-Za-z0-9]{32}#', $hash) === 1)
{
return md5($password . substr($hash, 33)) == substr($hash, 0, 32);
}
return false;
}
}