加密邮件,散列密码,并将其存储在DB中


Encrypting Emails, Hashing Passwords, and Storing them in DB?

首先,我对加密和散列的理解:

  1. 加密—可解密
  2. 散列-不能解散列

构建web应用程序时,我应该:

  1. 使用加密密钥加密电子邮件地址(将用于登录)。能够解密电子邮件地址以供以后使用(例如给用户发电子邮件)是很好的
  2. 用盐对密码进行散列。没有人能够看到用户的密码,所以哈希(因为它是单向的)是好的。

如果以上两点是正确的,我应该在哪里存储加密密钥和盐?

如果我将它存储在数据库中,如果数据库被破坏,这似乎有点毫无意义。这样做的好处是,我可以为每个用户分配唯一的加密密钥和盐。

我应该在应用程序的配置中存储加密密钥和盐吗?如果数据库被泄露,至少加密密钥和盐不会被泄露(希望如此)。问题是,这可能意味着每个人都共享相同的加密密钥和盐。

有什么建议吗?

如果要加密电子邮件,则需要使用普通的salt/key。否则,您将如何根据用户的电子邮件地址从数据库中选择用户来检查散列密码是否正确?你不可能每次都解密每个电子邮件地址。

总的来说,我认为加密电子邮件地址几乎没有什么好处。如果你想的话,可以使用MySQL数据库加密,但不要在应用程序级别担心这个问题。

用于散列密码的盐应该/需要是唯一的,并且可以存储在数据库中,实际上它可以是散列本身的一部分。

我觉得你的理解似乎是正确的。

Password:只存储密码的哈希值,以及用户指定的盐。盐可以以明文形式存储,盐的原因是攻击者不能为所有用户使用一个rainbowtable(构建一个rainbowtable是昂贵的)。建议使用hash_hmac()函数

EMail:我认为加密这些地址是一个好主意,但无论你怎么做,如果攻击者控制了服务器,他将能够恢复这些地址。我会把一个秘密密钥放在一个单独的目录,这是外部的web根(不能直接从web访问)。不要把它写在不需要解释就可以交付的文件中,扩展名*.php比*更好。公司。如果您无法访问这样的目录,至少创建一个目录,并使用.htaccess Deny from all保护它。

如果你需要在DB中找到一个电子邮件地址,你可以额外存储一个散列,这允许搜索不区分大小写(首先转换为小写,然后生成散列)。

盐应该是每个用户的,并且可以在数据库中;因此,盐的意义在于,拥有您的数据库副本的人无法一次破解所有密码,而是分别破解每个密码。

至于加密密钥,这是一个更困难的问题-绝对不要将其存储在数据库中;如果您的平台提供任何类型的受保护存储,您可能希望使用它。在MySQL中使用/存储加密密钥的最佳方法是什么?