代码改变世界

php 表单加密验证

2012-08-23 17:05  youxin  阅读(770)  评论(0编辑  收藏  举报

SHA-1 is considered secure because it’s said to be computationally infeasible to work out the
original text or to find two sets of text that produce the same number. This means that even if
your password file is exposed, no one will be able to work out what the passwords are. It also
means that you have no way of converting fe228bd899980a7e23fd08082afddb74a467e467
back to codeslave. In one respect, this is unimportant: when a user logs in, you encrypt the
password again and compare the two encrypted versions. The disadvantage is that there is

no way that you can send users password reminders if they forget them; you must generate
a new password. Nevertheless, good security demands encryption.
Another precaution that’s worth taking is adding a salt to the password before encrypting
it. This is a random value that’s added to make decryption even harder. Even if two people
choose the same password, adding a unique value to the password before encryption
ensures that the encrypted values are different. Sounds difficult? Not really, as you’ll see
over the next few pages.
You need to create a user registration form that checks the following:
The password and username contain a minimum number of characters.
The password matches a second entry in a confirmation field.
The username isn’t already in use.

表单如下:

<form id="form1" name="form1" method="post" action="">
    <p>
        <label for="username">Username:</label>
        <input type="text" name="username" id="username" />
    </p>
    <p>
        <label for="pwd">Password:</label>
        <input type="password" name="pwd" id="pwd" />
    </p>
    <p>
        <label for="conf_pwd">Confirm password:</label>
        <input type="password" name="conf_pwd" id="conf_pwd" />
    </p>
    <p>
        <input name="register" type="submit" id="register" value="Register" />
    </p>
</form>

现在你

// check length of username and password
$username = trim($_POST['username']);
$pwd = trim($_POST['pwd']);
if (strlen($username) < 6 || strlen($pwd) < 6) {
$result = 'Username and password must contain at least 6 characters';
}

You could check that strlen() is greater than 5. However, you still need to make
sure that both passwords match. Consequently, it’s more efficient to turn the logic
around and test for things that you don’t want. In pseudo-code, the logic works
like this:

if (username or password has less than the minimum) {
input is not OK
}
elseif (the passwords do not match) {
input is not OK
}
else {
input is OK to process
}

我们要把密码保存到文件里,fopen用什么模式。

Ideally, you want the internal pointer at the beginning of the file so that you can loop
through existing records. The r+ mode does this, but the operation fails unless the file
already exists. You can’t use w+, because it deletes existing content. You can’t use x+ either,
because it fails if a file of the same name already exists. That leaves a+ as the only option
with the flexibility you need: it creates the file if necessary, and lets you read and write.
The file is empty the first time you run the script (you can tell because the filesize()
function returns 0), so you can go ahead and write the details. If filesize() doesn’t
return 0, you need to reset the internal pointer and loop through the records to see if the
username is already registered. If there’s a match, you break out of the loop and prepare
an error message. If there isn’t a match by the end of the loop, you not only know it’s a
new username, you also know you’re at the end of the file. So, you write a new line followed
by the new record. Now that you understand the flow of the script, you can insert
it into register.php.

完整程序如下:

<?php
// execute script only if form has been submitted
if (array_key_exists('register', $_POST)) {
  // remove backslashes from the $_POST array
  include('../includes/corefuncs.php');
  nukeMagicQuotes();
  // check length of username and password
  $username = trim($_POST['username']);
  $pwd = trim($_POST['pwd']);
  if (strlen($username) < 6 || strlen($pwd) < 6) {
    $result = 'Username and password must contain at least 6 characters';
    }
  // check that the passwords match
  elseif ($pwd != $_POST['conf_pwd']) {
    $result = 'Your passwords don\'t match';
    }
  // continue if OK
  else {
    // encrypt password, using username as salt
    $pwd = sha1($username.$pwd);
    // define filename and open in read-write append mode
    $filename = 'C:/private/encrypted.txt';
    $file = fopen($filename, 'r');
    // if filesize is zero, no names yet registered
    // so just write the username and password to file
    if (filesize($filename) === 0) {
      fwrite($file, "$username, $pwd");
      }
    // if filesize is greater than zero, check username first
    else {
      // move internal pointer to beginning of file
      rewind($file);
      // loop through file one line at a time
      while (!feof($file)) {
        $line = fgets($file);
        // split line at comma, and check first element against username
        $tmp = explode(', ', $line);
        if ($tmp[0] == $username) {
          $result = 'Username taken - choose another';
          break;
          }
        }
      // if $result not set, username is OK
      if (!isset($result)) {
        // insert line break followed by username, comma, and password
        fwrite($file, "\r\n$username, $pwd");
        $result = "$username registered";
        }
      // close the file
      fclose($file);
      }
    }
  }
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Register user</title>
</head>

<body>
<h1>Register user</h1>
<?php
if (isset($result)) {
  echo "<p>$result</p>";
  }
?>
<form id="form1" name="form1" method="post" action="">
    <p>
        <label for="username">Username:</label>
        <input type="text" name="username" id="username" />
    </p>
    <p>
        <label for="pwd">Password:</label>
        <input type="password" name="pwd" id="pwd" />
    </p>
    <p>
        <label for="conf_pwd">Confirm password:</label>
        <input type="password" name="conf_pwd" id="conf_pwd" />
    </p>
    <p>
        <input name="register" type="submit" id="register" value="Register" />
    </p>
</form>
</body>
</html>

登录改成:

$username = trim($_POST['username']);
$pwd = sha1($username.trim($_POST['pwd']));