我正在构建一个Web服务,其中一个包含的功能涉及为用户外部应用程序存储密码和凭据 .
我的应用程序是使用PHP / Laravel构建的,我实现的当前安全措施是:
-
电子邮件和密码登录,并使用Google身份验证器进行强制性双因素身份验证
-
一旦用户进入,他们需要再次键入主密码以访问其外部应用程序的凭据数据库 .
-
CSRF保护和SSL
密码存储在MySQL数据库中,并使用Laravel的encrypt()方法进行加密,并且仅解密(使用decrypt()方法),并且如果经过身份验证的用户会话ID与使用密码凭据的行中的ID匹配,则会将密码提供给用户 .
当用户请求密码凭证时,它使用AJAX从数据库中提取,解密并复制到剪贴板,然后使用javascript从客户端删除,因此密码仅在客户端可用几秒钟才能返回到数据库加密以前 .
编辑:加密和解密的密钥是Laravel的app密钥,它是存储在公共文件夹中可见服务器文件之外的环境文件中的单个密钥 .
我的应用程序是B2B SaaS,中型客户使用它意味着它需要安全 . 请指出您在我的方法中看到的任何缺陷或您认为相关的任何其他建议 .
1 回答
这样做的最好方法是不要这样做 .
换句话说:如果你可以逃脱不存储密码(即改为使用OAuth2),不要存储密码 . 你不想要额外的责任 .
话虽这么说,有时你实际上无法避免存储密码(例如IMAP集成) . 在这种情况下,在你彻底钻进杂草之前,总是start with a threat model .
如果有人攻击你的数据库(例如SQL注入),他们可以访问什么?
他们可以访问文件系统并读取加密密钥吗?
他们是否可以将目标用户帐户的密文重写到他们已经访问过的帐户的字段中,从而无需先获取加密密钥即可访问明文?
听起来你正在重新实现密码管理器 . 您可能希望将您的客户转向KeePassXC或1Password .
由于此解密不包括任何用户提供的机密,因此网络服务器必须能够解密所有用户的密码 . 因此,如果攻击者可以破解网络服务器,他们就可以免费获得所有用户的密码 .
如果您想要拥抱principle of least authority并使您的服务器无法解密您的用户密码 .
这意味着使用客户端加密,其中您的服务器是一个仅存储密文的黑盒子 .