如何代表用户为外部应用程序安全存储多个密码?

时间:2018-01-16 10:08:08

标签: php laravel security encryption password-encryption

我正在构建一个Web服务,其中一个功能涉及为用户外部应用程序存储密码和凭据。

我的应用程序是使用PHP / Laravel构建的,我实施的当前安全措施是:

  • 使用Google身份验证器进行强制性双因素身份验证的电子邮件和密码登录
  • 用户进入后,需要再次输入主密码才能访问其外部应用程序的凭据数据库。
  • CSRF保护和SSL

密码存储在MySQL数据库中,并使用Laravel的encrypt()方法进行加密,并且仅解密(使用decrypt()方法),并且如果经过身份验证的用户会话ID与使用密码的行中的ID匹配,则会将密码提供给用户凭证。

当用户请求密码凭证时,它是使用AJAX从数据库中提取的,解密并复制到剪贴板然后使用javascript从客户端删除,因此密码只能在客户端返回几秒钟才能返回仅在以前加密的数据库中。

编辑:加密和解密的密钥是Laravel的app密钥,它是存储在公共文件夹中可见服务器文件之外的环境文件中的单个密钥。

我的应用程序是B2B SaaS,适用于中型客户,这意味着它需要安全。请指出您在我的方法中看到的任何缺陷或您认为相关的任何其他建议。

1 个答案:

答案 0 :(得分:0)

做到这一点的最好方法是

以另一种方式:如果您可以不用存储密码而逃脱(即改用OAuth2),请不要存储密码。您不想承担额外的责任。

话虽如此,有时您实际上无法避免存储密码(例如IMAP集成)。在这种情况下,请始终start with a threat model,然后再深入杂草。

  • 如果有人入侵您的数据库(例如SQL注入),他们可以访问什么?
    • 他们可以访问文件系统并读取加密密钥吗?
    • 他们是否可以将目标用户帐户中的密文重写为他们已经可以访问的帐户的字段,从而无需先获取加密密钥就可以访问明文?
  

当用户使用AJAX从数据库中提取密码凭证时,将其解密并复制到剪贴板,然后使用javascript从客户端删除,因此密码在返回之前仅在客户端可用几秒钟

听起来您正在重新实现密码管理器。您可能想让客户转向KeePassXC或1Password之类的东西。

由于此解密不包括任何用户提供的机密,因此Web服务器必须能够解密您所有用户的密码。因此,如果攻击者可以入侵Web服务器,他们将免费获得所有用户密码。

如果您对重新设计密码管理器一无所知,那么您将希望使用principle of least authority,并使您的服务器无法解密用户的密码。

这意味着使用客户端加密,您的服务器是一个仅存储密文的黑匣子。