我正在开发一个密码管理器,它有两种形式的身份验证。
首先,用户使用他们的密码登录。我使用bcrypt安全地工作。
下一部分要棘手得多。用户保存的服务以JSON格式存储,如下所示:
{
"name":"facebook",
"login":"myemail@email.com",
"signup-email":"myemail@email.com",
"password":"121654754321",
"notes":"my security questions answer is \"blah blah blah\""
}
我打算将它存储在一个包含两个字段的数据库表中:id和data(AES256加密的JSON)。
到目前为止,我的设计是使用一个带有32个char盐(每个用户独有)的6位数字引脚来加密它。永远不会存储引脚。 salt存储在用户表中。
这样做有什么可能的缺陷?任何人都可以推荐一种更好的方法来实现它吗?
答案 0 :(得分:0)
该引脚是已知的并且仅由用户插入?而不是使用6位pin + salt来加密数据,您可以使用PBKDF2(基于密码的密钥派生函数)来生成基于该6位引脚(和盐)的安全加密密钥。这样,每个用户将拥有不同(且安全)的加密密钥。请注意,除此之外,您应始终使用可以附加(或预先)加密数据的不同且加密安全的生成IV。
你的实现的安全漏洞是你的pin + salt没有产生足够的熵的可能性,因为你没有谈论IV我认为你没有使用一个因此暴露可能的模式你的加密数据。
对于安全漏洞,我的实现取决于您的安全目标。对于大多数人来说,PBKDF2(根据PHP实现的hash_algos()
算法之一)足够安全,即使它更容易受到使用FPGA或GPU集群的攻击。如果你想避免它们,可以使用bcrypt生成一个使用这些技术更难攻击的密钥。
我建议你阅读this answer,其中提供了更深入的理由,说明为什么bcrypt比PBKDF2好一些
答案 1 :(得分:0)
您的系统带来了巨大的安全挑战,因为它充当中央密码存储库,从而使其成为一个选择目标。你最好的防御是无知:如果你不能解码它,攻击者也会很难做到这一点。此外,您不需要访问存储的数据,但用户(只有用户)才能访问。
您已完成/打算做的事情是正确的,因为您无法访问完整密钥。但为什么你使用6位数的引脚而不是标准的"密码/短语?您负责80%以上加密密钥的安全性,并且您已将所有这些加密密钥放在一个地方!攻击者只需要找出(非常弱)引脚添加到salt中以便读取数据。此外,如果您的系统遭到入侵,可以设法检索用户请求,以便提取引脚并访问用户的帐户。
如果解密密钥永远不会靠近您的系统,则数据会更安全。为了检索用户的通行列表,需要闯入该用户的计算机并以某种方式从页面中检索解密的数据。这在某些情况下完全可行,可能比闯入您的服务器更容易,但这只会授予对一个帐户的访问权限。这对你的其他用户来说非常好:D
越来越多的应用程序使用这种方法来实现类似的结果。例如,您经常会看到使用JavaScript完成的客户端AES解密。 zerobin project描述了这种机制。
如前所述,在加密密钥中只留下用户6个字节并不是非常强大。他们需要能够添加他们喜欢的熵。大小上限的密码通常是个坏主意(我个人讨厌那些告诉我简短我的密码必须如何)的人。
(这一点与前一点有关)
按键拉伸描述了采用标准"人类"密码并将其转换为更强大的加密密钥。它有许多应用程序,并且正在您正在构建的几种密码管理器中使用。
RSA' PBKDF2是众所周知的密钥扩展算法,用于许多安全应用程序。
当然,为了构建安全的系统,还需要解决几个问题: