<?php /** * cypt & check password * author: zweiwei * email: [email protected] * date: 2012/01/30 */ class Security { private static $defaultSalt = '}#f4ga~g%7hjg4&j(7mk?/!bj30ab-wi=6^7-$^R9F|GK5J#E6WT;IO[JN'; public static function cryptPassword($password, $uid=null) { self::isVaildPassword($password); $salt = self::generateSalt($uid); return md5(sha1($salt.$password)); } public static function checkPassword($cryptPassword, $password, $uid=null) { if(strlen($cryptPassword) !== 32) { throw new Exception("cryptPassword :".$cryptPassword." length is wrong!"); } self::isVaildPassword($password); $salt = self::generateSalt($uid); if(md5(sha1($salt.$password)) === $cryptPassword) { return true; } return false; } private static function generateSalt($uid=null) { $md5Str = is_null($uid) ? md5($uid) : md5(self::$defaultSalt); return substr($md5Str, 8, 16); } private static function isVaildPassword($password) { if(!$password || strlen($password) < 8) { throw new Exception("password :".$password." must be longer than 8"); } // contain ~!@#$%^&* if(!preg_match('/[~!@#$%^&]/', $password)) { throw new Exception("password :".$password." must contain special characters(~!@#$%^&)"); } } }
测试代码:
require_once 'PHPUnit/Autoload.php'; class SecurityTest extends PHPUnit_Framework_TestCase { public function testCryptPassword() { $cryptPassword = Security::cryptPassword('12345686000&$~', 123); $this->assertEquals(32, strlen($cryptPassword)); $cryptPassword = Security::cryptPassword('12345686000&$~'); $this->assertEquals(32, strlen($cryptPassword)); } public function testCheckPassword() { $this->assertTrue(Security::checkPassword(Security::cryptPassword('12345686000&$~', 123), '12345686000&$~', 123)); $this->assertFalse(Security::checkPassword(Security::cryptPassword('12345686000&$~', 123), '12345686000&$', 123)); } }
参考:
http://jinchishuxue.iteye.com/blog/1126271
http://woshixushigang.iteye.com/blog/1181423