用户注册与密码验证
在注册过程中我们的新用户将提供他们期望使用的密码(当然是已经通过了验证并且满足安全需要的)。使用像下面这样的代码,我们将存储用户名和密码散列值到数据库中:

图解1 用户输入他们的帐户信息
<?php
/* Store user details */
$passwordHash = sha1($_POST['password']);
$sql = 'INSERT INTO user (username,passwordHash) VALUES (?,?)';
$result = $db->query($sql, array($_POST['username'], $passwordHash));
?>
下一次用户登陆时,我们使用像下面这样的代码来检查他们的帐号:

图解2再次登陆
<?php
/* 检查用户信息 */
$passwordHash = sha1($_POST['password']);
$sql = 'SELECT username FROM user WHERE username = ? AND passwordHash = ?';
$result = $db->query($sql, array($_POST['username'], $passwordHash));
if ($result->numRows() < 1)
{ /* 拒绝登陆 */
echo 'Sorry, your username or password was incorrect!';
}
else
{ /* 用户登陆 */
printf('Welcome back %s!', $_POST['username']);}
?>
散列的类型
有很多的散列算法可以使用,一般常用的是MD5和SHA-1。在一些旧的系统中(包括很多Linux的变体)使用标准数据加密(DES)散列。由于长度只有56位,这种算法已经不再被认为是一种足够强壮的散列并且应该避免使用。
例子
在PHP中你可以使用函数md5和sha1生成散列值。md5返回一个128位的散列值(32个16进制字符),而sha1返回160位的散列值(40个16进制字符)。例如:
<?php
$string = 'PHP & Information Security';
printf("Original string: %s\n", $string);printf("MD5 hash: %s\n", md5($string));printf("SHA-1 hash: %s\n", sha1($string));
?>
这段代码将输出下面的内容:
Original string: PHP & Information Security
MD5 hash: 88dd8f282721af2c704e238e7f338c41
SHA-1 hash: b47210605096b9aa0129f88695e229ce309dd362
你还可以使用MySQL的内置函数password(),md5或者sha1生成散列值。password() 函数使用在MySQL自身的用户验证系统中。在MySQL4.1版本以前它返回一个16字节的字符串,4.1以及之后的版本它返回一个41字节的字符串(基于SHA-1两次散列)。MySQL版本3.23.2加入了md5()函数,之后的4.0.2版本又加入了sha1()函数。
mysql> select PASSWORD( 'PHP & Information Security' );
+------------------------------------------+
| PASSWORD( 'PHP & Information Security' ) |
+------------------------------------------+
| 379693e271cd3bd6 |
+------------------------------------------+
1 row in set (0.00 sec)
mysql> select MD5( 'PHP & Information Security' );
+-------------------------------------+
| MD5( 'PHP & Information Security' ) |
+-------------------------------------+
| 88dd8f282721af2c704e238e7f338c41 |
+-------------------------------------+
1 row in set (0.01 sec)
注意:不建议在你自己的应用中使用MySQL的password()函数——这个函数的算法已经改变了许多次,而且在4.1之前的版本中它相当的脆弱。
你可以使用MySQL来计算你的散列值而不是PHP。这个存储我们的用户从表单中填写的注册信息的例子将变成这样:
<?php
/* 存储用户信息 */
$sql = 'INSERT INTO user (username, passwordHash) VALUES (?, SHA1(?))';
$result = $db->query($sql, array($_POST['username'], $_POST['password']));
?>
(未完待续...)