Merge branch 'develop' of http://git.dev.yoho.cn/web/yohobuy into develop
Showing
6 changed files
with
379 additions
and
5 deletions
library/Plugin/AuthCode.php
0 → 100644
1 | +<?php | ||
2 | +namespace Plugin; | ||
3 | +/** | ||
4 | + * Enter description here... | ||
5 | + * | ||
6 | + * example: | ||
7 | + * <pre> | ||
8 | + * | ||
9 | + * </pre> | ||
10 | + * | ||
11 | + * @name Q_Utils_AuthCode | ||
12 | + * @version version (2009-10-22 上午10:45:12) | ||
13 | + * @package Q.Utils.AuthCode | ||
14 | + * @author ziyang liuziyang@360quan.com | ||
15 | + * @since 1.0 | ||
16 | + */ | ||
17 | + | ||
18 | +class AuthCode | ||
19 | +{ | ||
20 | + | ||
21 | + /** | ||
22 | + * 验证编码 | ||
23 | + * | ||
24 | + * @param String $string | ||
25 | + * @param String $operation | ||
26 | + * @param Integer $expiry | ||
27 | + * @param String $key | ||
28 | + * @return String | ||
29 | + */ | ||
30 | + private static function auth($string, $key, $expiry = 0, $operation = 'decode') | ||
31 | + { | ||
32 | + $ckey_length = 4; | ||
33 | + $key = md5($key); | ||
34 | + $keya = md5(substr($key, 0, 16)); | ||
35 | + $keyb = md5(substr($key, 16, 16)); | ||
36 | + $keyc = $ckey_length ? ($operation == 'decode' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : ''; | ||
37 | + $cryptkey = $keya . md5($keya . $keyc); | ||
38 | + $key_length = strlen($cryptkey); | ||
39 | + $string = $operation == 'decode' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string; | ||
40 | + $string_length = strlen($string); | ||
41 | + | ||
42 | + $result = ''; | ||
43 | + $box = range(0, 255); | ||
44 | + | ||
45 | + $rndkey = array(); | ||
46 | + for ($i = 0; $i <= 255; $i++) | ||
47 | + { | ||
48 | + $rndkey[$i] = ord($cryptkey[$i % $key_length]); | ||
49 | + } | ||
50 | + | ||
51 | + for ($j = $i = 0; $i < 256; $i++) | ||
52 | + { | ||
53 | + $j = ($j + $box[$i] + $rndkey[$i]) % 256; | ||
54 | + $tmp = $box[$i]; | ||
55 | + $box[$i] = $box[$j]; | ||
56 | + $box[$j] = $tmp; | ||
57 | + } | ||
58 | + | ||
59 | + for ($a = $j = $i = 0; $i < $string_length; $i++) | ||
60 | + { | ||
61 | + $a = ($a + 1) % 256; | ||
62 | + $j = ($j + $box[$a]) % 256; | ||
63 | + $tmp = $box[$a]; | ||
64 | + $box[$a] = $box[$j]; | ||
65 | + $box[$j] = $tmp; | ||
66 | + $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256])); | ||
67 | + } | ||
68 | + | ||
69 | + if ($operation == 'decode') | ||
70 | + { | ||
71 | + if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) | ||
72 | + { | ||
73 | + return substr($result, 26); | ||
74 | + } | ||
75 | + else | ||
76 | + { | ||
77 | + return false; | ||
78 | + } | ||
79 | + } | ||
80 | + else | ||
81 | + { | ||
82 | + return $keyc . str_replace('=', '', base64_encode($result)); | ||
83 | + } | ||
84 | + } | ||
85 | + /** | ||
86 | + * 解密 | ||
87 | + * | ||
88 | + * @param String $string | ||
89 | + * @param String $key | ||
90 | + * @param Integer $expiry | ||
91 | + * @return String | ||
92 | + */ | ||
93 | + public static function decode($string, $key, $expiry = 0) | ||
94 | + { | ||
95 | + return self::auth($string, $key, $expiry, __FUNCTION__); | ||
96 | + } | ||
97 | + | ||
98 | + /** | ||
99 | + * 加密 | ||
100 | + * | ||
101 | + * @param String $string | ||
102 | + * @param String $key | ||
103 | + * @param Integer $expiry | ||
104 | + * @return String | ||
105 | + */ | ||
106 | + public static function encode($string, $key, $expiry = 0) | ||
107 | + { | ||
108 | + return self::auth($string, $key, $expiry, __FUNCTION__); | ||
109 | + } | ||
110 | + | ||
111 | + /** | ||
112 | + * 获取编码 | ||
113 | + * | ||
114 | + * @param String $plaintext | ||
115 | + * @param String $salt | ||
116 | + * @param String $encryption | ||
117 | + * @param bool $show_encrypt | ||
118 | + * @return String | ||
119 | + */ | ||
120 | + public static function getCrypted($plaintext, $salt = '', $encryption = 'md5-hex', $show_encrypt = false) | ||
121 | + { | ||
122 | + $salt = self::getSalt($encryption, $salt, $plaintext); | ||
123 | + switch ($encryption) | ||
124 | + { | ||
125 | + case 'plain' : | ||
126 | + return $plaintext; | ||
127 | + case 'sha' : | ||
128 | + $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext)); | ||
129 | + return ($show_encrypt) ? '{SHA}' . $encrypted : $encrypted; | ||
130 | + case 'crypt' : | ||
131 | + case 'crypt-des' : | ||
132 | + case 'crypt-md5' : | ||
133 | + case 'crypt-blowfish' : | ||
134 | + return ($show_encrypt ? '{crypt}' : '') . crypt($plaintext, $salt); | ||
135 | + case 'md5-base64' : | ||
136 | + $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext)); | ||
137 | + return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted; | ||
138 | + case 'ssha' : | ||
139 | + $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext . $salt) . $salt); | ||
140 | + return ($show_encrypt) ? '{SSHA}' . $encrypted : $encrypted; | ||
141 | + case 'smd5' : | ||
142 | + $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext . $salt) . $salt); | ||
143 | + return ($show_encrypt) ? '{SMD5}' . $encrypted : $encrypted; | ||
144 | + case 'aprmd5' : | ||
145 | + $length = strlen($plaintext); | ||
146 | + $context = $plaintext . '$apr1$' . $salt; | ||
147 | + $binary = self::_bin(md5($plaintext . $salt . $plaintext)); | ||
148 | + for ($i = $length; $i > 0; $i -= 16) | ||
149 | + { | ||
150 | + $context .= substr($binary, 0, ($i > 16 ? 16 : $i)); | ||
151 | + } | ||
152 | + for ($i = $length; $i > 0; $i >>= 1) | ||
153 | + { | ||
154 | + $context .= ($i & 1) ? chr(0) : $plaintext[0]; | ||
155 | + } | ||
156 | + $binary = self::_bin(md5($context)); | ||
157 | + | ||
158 | + for ($i = 0; $i < 1000; $i++) | ||
159 | + { | ||
160 | + $new = ($i & 1) ? $plaintext : substr($binary, 0, 16); | ||
161 | + if ($i % 3) | ||
162 | + { | ||
163 | + $new .= $salt; | ||
164 | + } | ||
165 | + if ($i % 7) | ||
166 | + { | ||
167 | + $new .= $plaintext; | ||
168 | + } | ||
169 | + $new .= ($i & 1) ? substr($binary, 0, 16) : $plaintext; | ||
170 | + $binary = self::_bin(md5($new)); | ||
171 | + } | ||
172 | + | ||
173 | + $p = array(); | ||
174 | + for ($i = 0; $i < 5; $i++) | ||
175 | + { | ||
176 | + $k = $i + 6; | ||
177 | + $j = $i + 12; | ||
178 | + if ($j == 16) | ||
179 | + { | ||
180 | + $j = 5; | ||
181 | + } | ||
182 | + $p[] = self::_toAPRMD5((ord($binary[$i]) << 16) | (ord($binary[$k]) << 8) | (ord($binary[$j])), 5); | ||
183 | + } | ||
184 | + | ||
185 | + return '$apr1$' . $salt . '$' . implode('', $p) . self::_toAPRMD5(ord($binary[11]), 3); | ||
186 | + | ||
187 | + case 'md5-hex' : | ||
188 | + | ||
189 | + default : | ||
190 | + $encrypted = ($salt) ? md5($plaintext . $salt) : md5($plaintext); | ||
191 | + return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted; | ||
192 | + } | ||
193 | + } | ||
194 | + | ||
195 | + /** | ||
196 | + * Enter description here... | ||
197 | + * | ||
198 | + * @param unknown_type $encryption | ||
199 | + * @param unknown_type $seed | ||
200 | + * @param unknown_type $plaintext | ||
201 | + * @return unknown | ||
202 | + */ | ||
203 | + public static function getSalt($encryption = 'md5-hex', $seed = '', $plaintext = '') | ||
204 | + { | ||
205 | + switch ($encryption) | ||
206 | + { | ||
207 | + case 'crypt' : | ||
208 | + case 'crypt-des' : | ||
209 | + if ($seed) | ||
210 | + { | ||
211 | + return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 2); | ||
212 | + } | ||
213 | + else | ||
214 | + { | ||
215 | + return substr(md5(mt_rand()), 0, 2); | ||
216 | + } | ||
217 | + break; | ||
218 | + | ||
219 | + case 'crypt-md5' : | ||
220 | + if ($seed) | ||
221 | + { | ||
222 | + return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 12); | ||
223 | + } | ||
224 | + else | ||
225 | + { | ||
226 | + return '$1$' . substr(md5(mt_rand()), 0, 8) . '$'; | ||
227 | + } | ||
228 | + break; | ||
229 | + | ||
230 | + case 'crypt-blowfish' : | ||
231 | + if ($seed) | ||
232 | + { | ||
233 | + return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 16); | ||
234 | + } | ||
235 | + else | ||
236 | + { | ||
237 | + return '$2$' . substr(md5(mt_rand()), 0, 12) . '$'; | ||
238 | + } | ||
239 | + break; | ||
240 | + | ||
241 | + case 'ssha' : | ||
242 | + if ($seed) | ||
243 | + { | ||
244 | + return substr(preg_replace('|^{SSHA}|', '', $seed), -20); | ||
245 | + } | ||
246 | + else | ||
247 | + { | ||
248 | + return mhash_keygen_s2k(MHASH_SHA1, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4); | ||
249 | + } | ||
250 | + break; | ||
251 | + | ||
252 | + case 'smd5' : | ||
253 | + if ($seed) | ||
254 | + { | ||
255 | + return substr(preg_replace('|^{SMD5}|', '', $seed), -16); | ||
256 | + } | ||
257 | + else | ||
258 | + { | ||
259 | + return mhash_keygen_s2k(MHASH_MD5, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4); | ||
260 | + } | ||
261 | + break; | ||
262 | + | ||
263 | + case 'aprmd5' : | ||
264 | + /* 64 characters that are valid for APRMD5 passwords. */ | ||
265 | + $APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; | ||
266 | + | ||
267 | + if ($seed) | ||
268 | + { | ||
269 | + return substr(preg_replace('/^\$apr1\$(.{8}).*/', '\\1', $seed), 0, 8); | ||
270 | + } | ||
271 | + else | ||
272 | + { | ||
273 | + $salt = ''; | ||
274 | + for ($i = 0; $i < 8; $i++) | ||
275 | + { | ||
276 | + $salt .= $APRMD5{rand(0, 63)}; | ||
277 | + } | ||
278 | + return $salt; | ||
279 | + } | ||
280 | + break; | ||
281 | + | ||
282 | + default : | ||
283 | + $salt = ''; | ||
284 | + if ($seed) | ||
285 | + { | ||
286 | + $salt = $seed; | ||
287 | + } | ||
288 | + return $salt; | ||
289 | + break; | ||
290 | + } | ||
291 | + } | ||
292 | + | ||
293 | + public static function genRandom($length = 8) | ||
294 | + { | ||
295 | + $salt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | ||
296 | + $len = strlen($salt); | ||
297 | + $makepass = ''; | ||
298 | + | ||
299 | + $stat = @stat(__FILE__); | ||
300 | + if (empty($stat) || !is_array($stat)) | ||
301 | + $stat = array( | ||
302 | + php_uname() | ||
303 | + ); | ||
304 | + | ||
305 | + mt_srand(crc32(microtime() . implode('|', $stat))); | ||
306 | + | ||
307 | + for ($i = 0; $i < $length; $i++) | ||
308 | + { | ||
309 | + $makepass .= $salt[mt_rand(0, $len - 1)]; | ||
310 | + } | ||
311 | + | ||
312 | + return $makepass; | ||
313 | + } | ||
314 | + | ||
315 | + public static function _toAPRMD5($value, $count) | ||
316 | + { | ||
317 | + /* 64 characters that are valid for APRMD5 passwords. */ | ||
318 | + $APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; | ||
319 | + $aprmd5 = ''; | ||
320 | + $count = abs($count); | ||
321 | + while (--$count) | ||
322 | + { | ||
323 | + $aprmd5 .= $APRMD5[$value & 0x3f]; | ||
324 | + $value >>= 6; | ||
325 | + } | ||
326 | + return $aprmd5; | ||
327 | + } | ||
328 | + | ||
329 | + public static function _bin($hex) | ||
330 | + { | ||
331 | + $bin = ''; | ||
332 | + $length = strlen($hex); | ||
333 | + for ($i = 0; $i < $length; $i += 2) | ||
334 | + { | ||
335 | + $tmp = sscanf(substr($hex, $i, 2), '%x'); | ||
336 | + $bin .= chr(array_shift($tmp)); | ||
337 | + } | ||
338 | + return $bin; | ||
339 | + } | ||
340 | + | ||
341 | + /** | ||
342 | + * 组合一个安全的密码 | ||
343 | + * @param $code | ||
344 | + * @return String | ||
345 | + */ | ||
346 | + public static function makePass($code) | ||
347 | + { | ||
348 | + $salt = self::genRandom(32); | ||
349 | + $crypt = self::getCrypted($code . $salt, $salt); | ||
350 | + return $crypt . ':' . $salt; | ||
351 | + } | ||
352 | + | ||
353 | + /** | ||
354 | + * 验证密码 | ||
355 | + * | ||
356 | + * @param String $inputPassword | ||
357 | + * @param String $password | ||
358 | + * @return bool | ||
359 | + */ | ||
360 | + public static function authPassword($inputPassword, $password) | ||
361 | + { | ||
362 | + if (empty($password) || empty($inputPassword)) | ||
363 | + { | ||
364 | + return false; | ||
365 | + } | ||
366 | + $passwordList = explode(':', trim($password)); | ||
367 | + if (count($passwordList) != 2) | ||
368 | + { | ||
369 | + return false; | ||
370 | + } | ||
371 | + list($crypt, $salt) = $passwordList; | ||
372 | + $decode = self::getCrypted($inputPassword . $salt, $salt); | ||
373 | + if ($crypt != $decode) | ||
374 | + { | ||
375 | + return false; | ||
376 | + } | ||
377 | + return true; | ||
378 | + } | ||
379 | +} |
-
Please register or login to post a comment