在php中使用preg_match验证密码

时间:2011-01-25 17:16:44

标签: php mysql regex passwords preg-match

我需要验证密码。我目前使用:  preg_match("/^[a-z0-9_-]*$/i", $pass)

我想为此添加长度。我的mysql表设置如下:userpassword varchar (40) NOT NULL,。所以在6到40个字符之间。我想允许所有没有危险的字符放入我的数据库中。

5 个答案:

答案 0 :(得分:8)

对密码施加任意复杂性规则对用户非常不利,并且不会大幅提高安全性。不要这样做。

这就是为什么认为上述陈述是正确的:

  • 如果我想将您的网站用“123456”作为我的密码,那就是我的问题。让我滚动吧。
  • 您可以施加最小长度(例如6个字符),但不是最大长度。如果我想引用整个John Maynard作为我的密码,请让我滚动它。
  • 您对“安全”密码的想法可能不是其他人的想法。
  • 人们可能会使用不会自动遵守规则集的password generators。不要因为没有包含足够/或太多“特殊字符”的其他原因而不接受他们的密码而烦扰他们。
  • 必须使用decent hashing algorithm加上随机hash salt哈希客户的密码,每个用户都有不同的密码。仅在数据库中存储哈希值和哈希值,从不存储明文密码。
  • 一旦进行了哈希处理,即使是蹩脚的密码也可以防止盗窃/破解。实施针对暴力攻击的安全措施(基于时间的锁定,基于IP的锁定,使用电子邮件握手进行密码锁定以检索锁定的帐户)。

所以你的密码验证过程就像这样

  • 新用户?使用用户名和随机盐创建用户记录(永远不要更改该用户的salt值)
  • 回归用户?从DB中获取salt,重新哈希他的密码,将结果与数据库中的哈希进行比较。
  • 切勿将用户密码存储在物理位置,并使用HTTPS进行传输。
  • 如果您不想执行上述操作,请考虑在您的网站上使用OAuth。也许并不容易,但您不必再担心密码安全您的用户只需要记住一个密码。

为了论证,这个正则表达式会按照你的要求行事。如果你仍然迫不及待地去做。

preg_match("/^[a-z0-9_-]{6,40}$/i", $pass)

答案 1 :(得分:2)

您应该通过确保密码安全来验证密码,而不是确保密码不安全。

public function password_is_secure($password) {
  // quick obvious test
  if (is_numeric($password)) {
    // FAIL: 'Your password cannot be all numbers.'
  } elseif (strlen(count_chars($password, 3)) < 4) {
    // FAIL: 'Your password needs to have a variety of different characters.'
  }

  // levenshtein distance test (test similarity to common passwords)
  $name = $_POST['name'];
  $email = $_POST['email'];
  $badPasswords = array($name, $email, 'password', 'password1', 'password123', '1234abcd', 'abcd1234', '12345678', '1234567890');

  foreach($badPasswords as $bad) {
    if (levenshtein($password, $bad) < 6) {
      // FAIL: 'Your password is too similar to your name or email address or other common passwords.'
    }
  }

  return true;
}

插件更适合$name$email的“getters”,并设置您希望如何处理传递错误消息,上述方法将为您提供一些正义。您可以通过改变允许的Levenschtein距离(目前为6)来“调整”它。

我还建议扩展$badPasswords列表以包含一堆most common passwords

为了爱一些神,在将密码存储到数据库之前对其进行加密和哈希。

答案 2 :(得分:2)

我想提供以下提示:

OpenID,Facebook Connect

您应该 在您的数据库中存储密码。通过非常简单的OpenID使用LightOpenID,原因如下:

最好不要

P.S:为了它的乐趣。如果他的登录系统是好的/安全的(它不是),那么有人在stackoverflow.com上问我,所以I wrote a SAFE login system。如果您使用SSL(如果我没有错过任何漏洞,但我不相信我这样做。)

长度/安全

  

我想为此添加长度。我的   mysql表设置如下:   userpassword varchar(40)NOT NULL,。   所以在6到40个字符之间。和我   想要允许所有角色   这对我来说并不危险   分贝。

我不喜欢正则表达式,因为它们过于复杂(我只是用作最后的努力)。我建议你只使用PHP(>5.2.0) which has protection in place to make it safe against XSS的最新版本。

  

过滤器扩展名已启用   默认自PHP 5.2.0起。在这之前   时间实验PECL扩展   但是,使用的是PECL版本   不再推荐或更新。

下一个验证长度就像使用strlen函数一样简单。

答案 3 :(得分:1)

您应该对密码进行哈希处理,如果您的数据库被破解,攻击者可以读取所有密码。

更新:检查 Tomalak 的帖子

      sha1($_POST['pass']); // will encrypt the password to a 40 character long string.
      echo(sha1('monkey')); // will become:          ab87d24bdc7452e55738deb5f868e1f16dea5ace
      echo(sha1('Monkey')); // completely different: 4bd0ec65b8f729d265faeba6fa933846d7c2d687
      // Just by making the letter upper-case!

如果您想登录用户,请从登录表单加密传递并将其与数据库进行比较。

      $pass = 'monkey';
      if(sha1($pass)=='ab87d24bdc7452e55738deb5f868e1f16dea5ace'){
          echo('Correct pass!');
      } 

如果要验证密码的长度,可以使用以下代码:

    if($upass=='' || $upass=='Password'){
        $errupass = 'Please fill in a password.';
        $valid = false;
    }elseif(strlen($upass)<6){
        $errupass = 'Password must be atleast 6 characters.';
        $valid = false;
    }

我不应该阻止人们使用奇怪的字符,因为它们会增加密码的强度。

答案 4 :(得分:0)

嗯,首先,您不会将纯文本密码输入数据库,因为您将首先以加密方式对其进行哈希处理。因此,您并不关心将哪些字符放入数据库或者没有危险,因为您将获得固定长度的字母数字字符串。

散列之前的正则表达式将类似于:

/^([a-zA-Z0-9]{6,40})$/

...在字符类括号中放置您想要允许的任何字符。

其次,您并不真正关心在插入查询中使用占位符时放入数据库的字符,对吗?