Mysql 使用储存在海螺中的盐

Mysql 使用储存在海螺中的盐,mysql,Mysql,考虑以下查询,该查询返回相同的输出,无论用户名是否无效或密码是否错误(只是一个示例,我知道SQL注入): 我想添加一个salt字段,但与其在应用程序中检索并连接,不如让MySQL在引擎中进行连接: CREATE TABLE users ( username VARCHAR(64), salt VARCHAR(128), password CHAR(40) ); SELECT FROM users WHERE username = '{$username}'

考虑以下查询,该查询返回相同的输出,无论用户名是否无效或密码是否错误(只是一个示例,我知道SQL注入):

我想添加一个salt字段,但与其在应用程序中检索并连接,不如让MySQL在引擎中进行连接:

CREATE TABLE users (
    username VARCHAR(64),
    salt VARCHAR(128),
    password CHAR(40)
);

SELECT FROM users
      WHERE username = '{$username}'
        AND password = sha1(CONCAT(<salt_field>, '{$password}'));
创建表用户(
用户名VARCHAR(64),
盐瓦查尔(128),
密码字符(40)
);
从用户中选择
其中username='{$username}'
密码=sha1(CONCAT(,'{$password}');

我应该用什么来代替

您可以根据需要引用任何列。在这种情况下,您可以使用
其中password=SHA1(CONCAT(salt,)
。请注意,仍然可以嗅探密码。你是否信任环境取决于你自己。下面的查询是一个很好的示例,但不太有用:
其中lastName=username
。在这种情况下,您将比较用户的姓氏和他们选择的用户名。因此,在本例中,它将返回所有用户名与姓氏相同的用户


当您连接多个表时也会发生这种情况。实际上,可以将第一个表的所有行与第二个表中的行连接起来,但只返回与给定条件匹配的行。巧妙的优化将导致不考虑所有可能的组合,而只考虑其中的一小部分。

您可以根据需要参考任何列。在这种情况下,您可以使用
其中password=SHA1(CONCAT(salt,)
。请注意,仍然可以嗅探密码。你是否信任环境取决于你自己。下面的查询是一个很好的示例,但不太有用:
其中lastName=username
。在这种情况下,您将比较用户的姓氏和他们选择的用户名。因此,在本例中,它将返回所有用户名与姓氏相同的用户


当您连接多个表时也会发生这种情况。实际上,可以将第一个表的所有行与第二个表中的行连接起来,但只返回与给定条件匹配的行。聪明的优化将导致不考虑所有可能的组合,而只考虑其中的一小部分。

sha1(CONCAT(salt,{$password}'))
。Salt引用用户表中的列,就像使用联接或select查询该列一样。不应将普通密码放入查询中,因为启用的查询日志记录将公开密码。在应用程序中进行哈希运算,而不是在SQL中进行。@Caramiriel:谢谢,请将其作为答案发布,以便我接受。@fab:为此,“真实”查询实际上是双重哈希运算,因此最终结果是
md5(concat(salt,md5(密码))
。谢谢。
sha1(CONCAT(salt,{$password}'))
。Salt引用用户表中的列,就像使用联接或select查询该列一样。不应将普通密码放入查询中,因为启用的查询日志记录将公开密码。在应用程序中进行哈希运算,而不是在SQL中进行。@Caramiriel:谢谢,请将其作为答案发布,以便我接受。@fab:为此,“真实”查询实际上是双重哈希运算,因此最终结果是
md5(concat(salt,md5(密码))
。谢谢。谢谢你把这个问题放在我熟悉这个概念的地方。谢谢你把这个问题放在我熟悉这个概念的地方。
CREATE TABLE users (
    username VARCHAR(64),
    salt VARCHAR(128),
    password CHAR(40)
);

SELECT FROM users
      WHERE username = '{$username}'
        AND password = sha1(CONCAT(<salt_field>, '{$password}'));