SimpleCryptPassword.php
4.61 KB
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
<?php
/**
* Joomla! Content Management System
*
* @copyright Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.
* @license GNU General Public License version 2 or later; see LICENSE.txt
*/
namespace Joomla\CMS\Crypt\Password;
defined('JPATH_PLATFORM') or die;
use Joomla\CMS\Crypt\Crypt;
use Joomla\CMS\Crypt\CryptPassword;
/**
* Joomla Platform Password Crypter
*
* @since 3.0.1
* @deprecated 4.0 Use PHP 5.5's native password hashing API
*/
class SimpleCryptPassword implements CryptPassword
{
/**
* @var integer The cost parameter for hashing algorithms.
* @since 3.0.1
* @deprecated 4.0 Use PHP 5.5's native password hashing API
*/
protected $cost = 10;
/**
* @var string The default hash type
* @since 3.1.4
* @deprecated 4.0 Use PHP 5.5's native password hashing API
*/
protected $defaultType = '$2y$';
/**
* Creates a password hash
*
* @param string $password The password to hash.
* @param string $type The hash type.
*
* @return mixed The hashed password or false if the password is too long.
*
* @since 3.0.1
* @throws \InvalidArgumentException
* @deprecated 4.0 Use PHP 5.5's native password hashing API
*/
public function create($password, $type = null)
{
if (empty($type))
{
$type = $this->defaultType;
}
switch ($type)
{
case '$2a$':
case CryptPassword::BLOWFISH:
$type = '$2a$';
if (Crypt::hasStrongPasswordSupport())
{
$type = '$2y$';
}
$salt = $type . str_pad($this->cost, 2, '0', STR_PAD_LEFT) . '$' . $this->getSalt(22);
return crypt($password, $salt);
case CryptPassword::MD5:
$salt = $this->getSalt(12);
$salt = '$1$' . $salt;
return crypt($password, $salt);
case CryptPassword::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 3.0.1
* @deprecated 4.0 Use PHP 5.5's native password hashing API
*/
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 3.0.1
* @deprecated 4.0 Use PHP 5.5's native password hashing API
*/
protected function getSalt($length)
{
$bytes = ceil($length * 6 / 8);
$randomData = str_replace('+', '.', base64_encode(Crypt::genRandomBytes($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 3.0.1
* @deprecated 4.0 Use PHP 5.5's native password hashing API
*/
public function verify($password, $hash)
{
// Check if the hash is a blowfish hash.
if (substr($hash, 0, 4) == '$2a$' || substr($hash, 0, 4) == '$2y$')
{
$type = '$2a$';
if (Crypt::hasStrongPasswordSupport())
{
$type = '$2y$';
}
return password_verify($password, $hash);
}
// Check if the hash is an MD5 hash.
if (substr($hash, 0, 3) == '$1$')
{
return Crypt::timingSafeCompare(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)
{
// Check the password
$parts = explode(':', $hash);
$salt = @$parts[1];
// Compile the hash to compare
// If the salt is empty AND there is a ':' in the original hash, we must append ':' at the end
$testcrypt = md5($password . $salt) . ($salt ? ':' . $salt : (strpos($hash, ':') !== false ? ':' : ''));
return Crypt::timingSafeCompare($hash, $testcrypt);
}
return false;
}
/**
* Sets a default type
*
* @param string $type The value to set as default.
*
* @return void
*
* @since 3.1.4
* @deprecated 4.0 Use PHP 5.5's native password hashing API
*/
public function setDefaultType($type)
{
if (!empty($type))
{
$this->defaultType = $type;
}
}
/**
* Gets the default type
*
* @return string $type The default type
*
* @since 3.1.4
* @deprecated 4.0 Use PHP 5.5's native password hashing API
*/
public function getDefaultType()
{
return $this->defaultType;
}
}