Php 不区分大小写的用户名和密码

Php 不区分大小写的用户名和密码,php,passwords,case-sensitive,salt,Php,Passwords,Case Sensitive,Salt,我有一个登录系统 其中,例如,Joe可以使用用户名Joe登录,而不会出现任何问题 目前,我正在使用一种密码加密,它使用用户名作为salt。这会造成登录问题。比如说, SELECT * FROM `users` WHERE LOWER(`username`) = LOWER(`:username`) $stmt->bindValue(':username', $_POST['user']); 这个很好用。问题涉及密码: SELECT * FROM `users` WHERE LOWER(`

我有一个登录系统

其中,例如,
Joe
可以使用用户名
Joe
登录,而不会出现任何问题

目前,我正在使用一种密码加密,它使用用户名作为salt。这会造成登录问题。比如说,

SELECT * FROM `users` WHERE LOWER(`username`) = LOWER(`:username`)
$stmt->bindValue(':username', $_POST['user']);
这个很好用。问题涉及密码:

SELECT * FROM `users` WHERE LOWER(`username`) = LOWER(`:username`)
   AND `password` = :password
$stmt->bindValue(':username', $_POST['user']);
$stmt->bindValue(':password', encrypt($_POST['password'], $_POST['user'])); //encrypt(password, salt)
如您所见,密码加密不会检查数据库,因为用户使用
joe
登录,而不是
joe

这有解决办法吗,还是我应该用别的东西作为盐?如果是,我应该用什么做盐?这是我的加密功能:

function encrypt($password, $salt) {
    return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($salt), $password, MCRYPT_MODE_CBC, md5(md5($salt))));
}

首先,使用strtolower($\u POST['user'])作为salt有什么问题?看起来会有用的

一般来说,盐是不可预测的。用户名并不是真的那么不可预测,因此,尽管这不会是世界末日,但如果您用一个随机生成的长度适中的字符串替换用户名(它不一定是加密强度随机的,只是不可预测的),您的用户安全性会更好


但是这里最大的问题是MD5的使用,一段时间以来一直被认为是不安全的。如果您切换到其他哈希函数,安全性将得到提高;SHA-1并不是一个特别糟糕的选择(它确实有一个不受欢迎的特性:计算速度很快),但最适合这种应用程序的是具有可变负载因子的哈希函数,例如
bcrypt

首先,使用
strtolower($\u POST['user'])
作为salt有什么问题?看起来会有用的

一般来说,盐是不可预测的。用户名并不是真的那么不可预测,因此,尽管这不会是世界末日,但如果您用一个随机生成的长度适中的字符串替换用户名(它不一定是加密强度随机的,只是不可预测的),您的用户安全性会更好


但是这里最大的问题是MD5的使用,一段时间以来一直被认为是不安全的。如果您切换到其他哈希函数,安全性将得到提高;SHA-1并不是一个特别糟糕的选择(它确实有一个不受欢迎的特性:计算速度很快),但最适合此类应用程序的是具有可变负载因子的哈希函数,如
bcrypt

跳过SQL
下限,使用PHP的。这样,您的用户名将在所有方面保持一致。

跳过SQL
的较低部分,使用PHP的。这样,您的用户名将在所有方面保持一致。

您遇到的问题是不应将用户名用作salt的原因之一。散列密码的更好方法是使用
crypt()
。你只需要生成一个随机的盐来使用它。它返回的字符串包含散列和散列算法,因此您可以在不重写代码的情况下更改算法或难度。只要你的散列是7位安全的,整个字符串都是安全的,所以你不需要
base64\u encode()
任何东西。

你遇到的问题是用户名不应该用作salt的一个原因。散列密码的更好方法是使用
crypt()
。你只需要生成一个随机的盐来使用它。它返回的字符串包含散列和散列算法,因此您可以在不重写代码的情况下更改算法或难度。只要您的哈希是7位安全的,整个字符串都是安全的,因此您不需要
base64\u encode()
任何东西。

这里有几个问题:

  • 您的salt的大小写敏感度
  • 您的密码“加密”方法
  • 第一个问题是你问的问题,所以让我们来看看。 因此,您的密码中会添加用户名,并且您希望能够使用用户在登录时输入的用户名作为salt。如果您确定了盐的标准化方案,这将起作用。在函数中使用它之前,请先将其转换为小写或大写,而不是按输入使用它

    另一个选项是对数据库执行两个查询:一个是在存储用户名时提取用户名,另一个是实际检查密码。这不是最好的,但它确实是你的麻烦最小的

    这有解决办法吗,还是我应该用别的东西作为盐?如果是,我应该用什么做盐

    既然你问了,让我们来看第二个问题:你的密码“加密”方法

    出于多种原因,尝试发明自己的密码哈希/加密方案从来都不是一个好主意。最好的选择是使用已经被广泛接受的密码散列方案,例如bcrypt或PBKDF2的一些衍生物。这些都很好,因为它们都包括盐渍和关键拉伸。它们被设计得很慢(无论如何,相对而言),因此强制使用这些类型的哈希在计算上非常昂贵

    使用上述密码散列方案之一也可以解决您的第一个问题,因为这些方案使用内置的每用户密码。根据您选择如何实施这些计划,您将不需要(不应该)提供您自己的salt。顶级库将为您生成盐

    尝试查看以下用于密码哈希的库:

    • -为PHP4编写,但也适用于最新版本。支持bcrypt,但如果不支持bcrypt(大部分情况下PHP<5.3),则会返回到其自己的方案
    • -很棒的库,但需要PHP 5.3+
    • -与Anthony的库相似,但实现方式不同。x分支试图更像Python的PassLib。还需要PHP5.3+

      • 这里有几个问题:

      • 您的salt的大小写敏感度
      • 您的密码“加密”方法
      • 第一个问题是你问的问题,所以让我们来看看。 所以哟