安全存储可解密密码的方法

8
我正在用PHP开发一个应用程序,有一个要求是必须能够解密密码,以便在将来切换用户数据库到不同系统时避免问题。考虑到无法修改这个未来系统的密码方法,我需要明文密码才能生成密码。
计划是使用存储在服务器上的公钥加密用户密码。身份验证是通过加密输入并比较结果来完成的。没有进行解密。用于解密的私钥存储在离线位置以供以后使用。
您建议使用哪种加密/解密算法?当您考虑到攻击者无法获得私钥时,加密后的密码是否仍然像哈希(MD5 / SHA1)一样安全?

8
MD5和SHA1不是加密,而是哈希。你在这里谈论的是加密还是哈希? - Matti Virkkunen
4
@Matti Virkkunen和erenon:问题是“当存储可解密密码但私钥存储在其他地方(对于Web服务器完全无法访问)时,密码是否仍然像MD5 / SHA1一样安全?” - VolkerK
1
@VolkerK 我不知道为什么你想要使用非对称加密来存储密码。这是CWE-257的违规行为。 - rook
1
如果服务器可以访问密钥(它需要验证密码),那么其他任何人也可以访问。 - poke
2
如果您需要更改密码存储系统,那么您可以在用户下次登录时更新密码哈希。 - rook
显示剩余14条评论
5个回答

8
我将重新表述Jammer的方法 -
  1. 生成一对公私钥。在您的Web服务器上硬编码公钥。将私钥存储在银行保险箱中,超出Web服务器/数据库/任何开发人员的范围。
  2. 用户注册时,使用公钥加密密码+盐。此步骤与使用哈希算法相同。将加密后的密码+盐存储在数据库中。
  3. 当您想要验证密码时,再次加密并将其与存储在数据库中的值进行比较。

如果攻击者获得了数据库,他无法解密密码,因为他没有私钥。他无法获得私钥,因为它位于他无法接触的银行保险箱中。由于盐的存在,相同的密码仍然会以不同的方式存储在数据库中。

我不建议使用以上方法,因为在未来的任何时刻,某个人都可以滥用私钥并访问所有密码。

但是,如果您保证私钥始终保持私密,则我认为这种方法没有技术缺陷。

当然,我可能是错的。


与仅对密码进行哈希处理相比,它在处理方面也相当昂贵。 - symcbean
@Sripathi 正确,但我应该使用什么算法? - Jammer
1
@symcbean,这可能会更昂贵,但我认为这不是问题。此外,任何攻击者在对数据库执行字典攻击时都需要花费更多的时间。 - Jammer
1
事实上,建议使用bcrypt来进行密码哈希的原因是因为它被设计成慢速的。 - Douglas Leeder
@Jammer - 你应该阅读这个帖子中的讨论 - https://dev59.com/1HE95IYBdhLWcg3wf-AF。虽然是一篇长篇讨论,但与你的问题非常相关。 - Sripathi Krishnan

5
不要解密密码。如果你需要在未来更改密码系统,添加一个名为storage_type(或其他名称)的字段。 然后,当你需要更改密码时,你将检查它是否是旧密码。如果是旧密码,在下次登录时,你可以更改密码编码。否则,使用新系统登录。

2
能够解密密码是一个坏主意(而且可能没有任何比存储未加密的密码更好的方法)。听起来你的主要问题是如果你改变存储方式,就无法使用密码。就像Linux一样,存储密码的哈希方式和密码一起。例如$1$salt$hash是MD5。这样,如果你决定改变密码的存储方式,你仍然可以检查旧密码(如果有人成功登录,你可以使用新哈希更新他们的密码)。

这将要求我修改未来的平台,而我宁愿不这样做。虽然将纯文本密码移动到那里也需要一些努力,但至少在一次性移动之后不需要任何管理工作。 - Jammer
你不能使用一些未来会被支持的东西吗?例如,SHA512 在几乎任何平台上都很容易实现(如果你能找到一个加密库,你可能也可以做 sha512)。 - Brendan Long
1
我同意,你不应该为了更容易地切换到下一个加密方法而牺牲安全性。一开始就选择好一种好的加密方法,你就不需要过多关注未来的任何变化。 - poke

1

我唯一看到的问题是,大多数公钥私钥加密代码都会使用公钥来加密对称密钥,并依赖于私钥来解密,然后使用对称密钥来加密消息。

您想要使用公钥直接加密密码+盐。

所以攻击您的系统归结为:

  1. 针对一般公共/私有密钥加密的攻击
  2. 针对您的私人密钥存储的攻击。

-1

对于大多数应用程序来说,存储密码的SHA-1哈希值已经足够了。

是的,大多数哈希算法都存在已知的碰撞,但这并不意味着实际攻击向量。特别是当您对哈希进行盐处理时。

对于您的盐:将其存储在配置文件中,该文件无法从外部访问,但可以被您的PHP安装读取。


你所提出的是一个已知的漏洞。我会在 BugTraq 上看到你的。 - rook
我正在寻找加密解决方案,而不是哈希。 - Jammer
1
仅存储单个盐值比不使用盐略好,为每个密码使用一个盐值是更好的选择。 - Brendan Long
1
这完全取决于你实际需要多少安全性。正如我所说的:对于大多数应用程序来说,简单的盐哈希就足够了。许多应用程序遗憾地也充满了自己的安全问题,不完美的哈希算法只是其中最小的问题。 - selfawaresoup

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接