|
发表于 2017-1-11 12:00:02
- class CryptHelper {
- /**
- * 加密
- * @param unknown $password
- * @param unknown $salt
- * @return string
- */
- public static function crypt($password,$salt){
- // $saltPrefix .= '$2y$'; // Blowfish 算法
- // $saltPrefix .= '13'; // 两位 cost 参数
- // $saltPrefix .= '$'; // 一个 $
- // $saltSuffix .= 'LGsF2ctmKKHE1yr2Py.vtu';
- return crypt($password, $salt);
- }
-
- /**
- * 字符比较
- * @param unknown $expected
- * @param unknown $actual
- * @return boolean
- */
- public static function compareString($expected, $actual)
- {
- $expected .= "\0";
- $actual .= "\0";
- $expectedLength = mb_strlen($expected, '8bit');
- $actualLength = mb_strlen($actual, '8bit');
- $diff = $expectedLength - $actualLength;
- for ($i = 0; $i < $actualLength; $i++) {
- $diff |= (ord($actual[$i]) ^ ord($expected[$i % $expectedLength]));
- }
- return $diff === 0;
- }
-
- /**
- * 校验密码
- * @param unknown $password
- * @param unknown $hash
- * @return boolean
- */
- public static function validatePassword($password, $hash)
- {
- if (!is_string($password) || $password === '') {
- return false;
- }
-
- if (!preg_match('/^\$2[axy]\$(\d\d)\$[\.\/0-9A-Za-z]{22}/', $hash, $matches)
- || $matches[1] < 4
- || $matches[1] > 30
- ) {
- return false;
- }
-
- $test = self::crypt($password, $hash);
- $n = strlen($test);
- if ($n !== 60) {
- return false;
- }
- return self::compareString($test, $hash);
- }
- }
复制代码
测试
- // --------- 测试 --------
- // 加密
- $salt = '$2y$13$LGsF2ctmKKHE1yr2Py.vtu'; // 7 + 22 == 29
- $password = 'Aa123456';
- echo CryptHelper::crypt($password,$salt);
- echo PHP_EOL;
- // 校验
- $hash = '$2y$13$LGsF2ctmKKHE1yr2Py.vtuiUR/A0C6tARkCxMO.LUlsiRISu7u53m';
- echo CryptHelper::crypt($password,$hash);
- echo PHP_EOL;
- echo strlen($hash);
- echo PHP_EOL;
- echo CryptHelper::validatePassword($password, $hash);
复制代码
|
|