我正在用PHP 5.3和 MySQL 创建一个网站。我需要一个小费。今天最好的加密和解密系统是什么?我知道 Sha1 和 MD5 被黑了...而且,如果有人知道一个安全系统,可以帮我举个例子来使用它吗?谢谢!
3 回答
“加密”和“解密”与散列不同,这是您真正追求的!PHP 5.5 将为使用 bcrypt 的强密码散列算法提供一个良好、简单的 API,bcrypt 是迄今为止为此目的最强大的公认算法之一。现在, password_compat在当前 PHP 版本中以向前兼容的实现方式启用了这个 API。
您听说它们被“破解”的原因是因为彩虹表已成为一种可行且流行的“破解”加密密码(尚未加盐)的方法。如果您想了解更多信息,可以在 google 上快速搜索MD5 Rainbow Table或对另一种加密算法进行相关搜索,这将提供许多有用的信息链接。
除了使用单向加密算法(如 MD5、SHA1 等)对密码进行加密之外,最安全的存储密码的方法是使用 salt。以下是实现加盐密码系统的步骤:
注意:这些只是向您展示如何使用随机盐对密码进行加盐的几个示例方法。为简洁起见,我省略了加密。如果您不知道如何使用 sha1()、md5() 或相关函数加密字符串,那么这对您没有多大帮助。
在数据库中安全存储(加盐)加密密码
你需要什么:
- PHP(最好是 5.3+!)
- SQL 数据库(例如 MySQL、MariaDB、PostgreSQL、Oracle、DB2 等)
- 能够从 PHP(mysqli、PDO 等)的 SQL 数据库中插入/检索行
- 能够在 PHP 中使用基本的加密算法函数(例如 sha1()、md5() 等)
1. 创建您的用户数据库并编写查询:
*注意:user_pass 长度为 40 个字符,因为本教程使用 SHA1,此数字将随加密算法而变化*
CREATE TABLE userbase (
user_id int(10) NOT NULL UNSIGNED AUTO_INCREMENT PRIMARY KEY,
user_name varchar(18) NOT NULL UNIQUE KEY,
user_pass char(40) CHARACTER SET utf8 COLLATE ut8_bin NOT NULL.
user_salt char(10) NOT NULL UNIQUE KEY,
user_email varchar(70) NOT NULL UNIQUE KEY
) ENGINE=innodb,CHARACTER SET=utf8, COLLATE=utf8_general_ci;
询问:
INSERT INTO `userbase`(`user_name`, `user_pass`,
`user_salt`, `user_email`)
VALUES(:name, :pass, :salt, :email);
2.编写注册脚本
public function getSalt()
// password should have already been validated
{
// retrieve random number within character index of SHA1 salt:
$i = mt_rand(1, 28);
// retrieve current unix time in seconds since midnight Jan 1, 1970:
$unixTime = time();
// take 10char substring of the SHA1 hash of $unixTime from random index:
return ($salt = substr(sha1($unixTime), $i, 10));
}
public function saltPass($salt, &$pass)
// precondition: salt has been generated, password has been checked
// postcondition: password is salted and ready for encryption
{
return ($pass .= $salt);
}
public function insertUser ($name, $pass, $salt, email, $dbConn)
// precondition: password has been salted and encrypted
// , email has been validated
// , username has been validated
// postcondition: user info is inserted into DB
{
// Store query in variable:
$query = "INSERT INTO `userbase`(`user_name`, `user_pass`
,`user_salt`, `user_email`)
VALUES(:name, :pass
,:salt, :email)";
// create new PDO (or MySQLi,etc) prepared statement:
$pdo = $dbConn->prepare($query);
//bind pdo named parameters:
$pdo->bindParam(':name', $name, PDO::PARAM_STR);
$pdo->bindParam(':pass', $pass, PDO::PARAM_STR);
$pdo->bindParam(':salt', $salt, PDO::PARAM_STR);
$pdo->bindParam(':email', $email, PDO::PARAM_STR);
// execute query:
$pdo->execute();
// get num of affected rows:
$rows = $pdo->rowCount();
return ($rows === 1) ? true : false;
}
授权步骤:
- 将用户提供的用户/密码(来自登录)存储在变量中
- 从数据库中检索密码/盐
- 根据数据库记录验证密码
- 设置会话变量
3.编写授权脚本:
public function getDbRecord($dbConn, $name, &$dbPass, &$dbSalt)
// precondition: dbPass and dbSalt have been initialized
// postcondition: dbPass and dbSalt contain db record
// , or are null if function returns false
{
// create query:
$query = "SELECT `user_pass` as 'pass', `user_salt` as 'salt'
FROM `userbase`
WHERE `user_name` = '". $dbConn->quote($name) ."'";
// exec query and return rows:
$pdo = $dbConn->query($query);
// bind columns to dbPass and dbSalt
$pdo->bindColumn('pass', $dbPass);
$pdo->bindColumn('salt', $dbSalt);
// fetch bound columns:
$result = $pdo->fetch(PDO::FETCH_BOUND);
if ($result === false)
return false;
else
return true;
}
public function validateUser($pass, $dbSalt, $dbPass)
// precondition: user exists and record retrieved via call to getDbRecord(...)
// postcondition: user is either authorized or not via $_SESSION['auth']
// , function returns true or false depending on value of $_S['auth']
{
// salt password with the same algorithm:
$pass .= $dbSalt;
// check password value:
if (sha1($pass) === $dbPass) {
$_SESSION['auth'] = TRUE;
return true;
} else {
$_SESSION['auth'] = FALSE;
return false;
}
}
其他选项:
您可能有兴趣查看具有本机加盐功能的MCRYPT 包。Mcrypt 不是开箱即用的,而是 PHP 扩展社区库的一部分。Mcrypt 提供了许多散列算法和本地加盐机制。
有关 mcrypt 的更多信息,请访问: http: //php.net/manual/en/book.mcrypt.php