假设我在将用户密码存储到我的数据库之前使用 bcrypt 和唯一的 salt(或其他一些最佳实践)来对用户密码进行哈希处理。
- 在加密之前对密码进行字符转换是否可以获得任何安全优势?(即
A -> B
,a -> b
,9 -> :
) - 通过在加密后对哈希进行字符移动可以获得任何安全优势,不包括
==
? (即AB+6/== -> BC,70==
) - 如果没有获得任何优势,这样做是否会失去安全性?或者是洗头?
鉴于基于标准密码模式的攻击的增加,隐藏这些模式是否有帮助?
假设我在将用户密码存储到我的数据库之前使用 bcrypt 和唯一的 salt(或其他一些最佳实践)来对用户密码进行哈希处理。
A -> B
, a -> b
, 9 -> :
)==
? (即AB+6/== -> BC,70==
)鉴于基于标准密码模式的攻击的增加,隐藏这些模式是否有帮助?
在散列密码之前对密码应用转换不会直接损害安全性,只要它是单射的:应用转换之前的两个不同的密码在转换后仍然应该是不同的。如果您正确地执行此操作,您的“字符转换”就可以了(即注意将值 255 的字节转换为值 0 的字节,这将“截断”密码)。
间接地,您的额外转换是额外的代码,因此会带来额外的复杂性,而复杂性总是对安全性不利。此外,如果转换的计算量很大,那么它与 PBKDF2/bcrypt 中使用的迭代计数不一致(即,可用的 CPU 较少,因此必须使用较低的迭代计数)。
只有在攻击者没有意识到这一点的情况下,您所设想的转换对安全性有任何好处,即攻击者没有做功课。刚刚幸运地进行 SQL 注入攻击的基本、低功率攻击者可能确实缺乏知识,但这些攻击者并不可怕。您的额外转换不会阻止强大的攻击者,这是您应该担心的强大攻击者。
在散列之后应用的转换对安全性没有任何影响,除非您使用额外散列之类的东西,在这种情况下,您只是尝试构建自定义散列函数,这通常是一个坏主意。所以不要这样做。使用 CPU 的正确方法是不要将其浪费在巫毒字符转换和其他仪式上;相反,请使用您的 CPU 使 bcrypt/PBKDF2 迭代计数尽可能高,以使您的整体应用程序性能能够承受。
不。
现代密码学的整个原则是你应该自动假设攻击者知道你的密码方案。你把你的计划当作秘密,这是个坏主意。
坚持正常的 bcrypt / PBKDF2。
加盐密码确实掩盖了这些模式。你基本上建议加盐两次。一次是用你自制的盐,然后是在 bcrypt 中。
这只会在您不知道您的自制盐但知道您与 bcrypt 一起使用的独特盐的情况下产生额外的安全性。
这种情况不应该发生。如果攻击者可以访问您的整个系统并且他也知道您自制的盐,则攻击者应该只知道您的 bcrypt 唯一盐。
一般来说,最好的做法是信任加密功能,而不是尝试实现自己的加密功能。在这种情况下,这意味着信任 bcrypt 可以正确地加盐,而不是自己尝试正确加盐。
您在移动字符时所做的是在散列过程中添加一个秘密。攻击者在计算哈希之前必须知道(或必须找出)你做了什么,否则他无法使用字典找到原始密码。
有更好的方法来添加这样的服务器端机密。您可以使用块密码(双向加密)加密已经散列的密码。要获取您的密钥,攻击者不仅需要对您的数据库进行读取访问(SQL 注入),还必须获得服务器上的权限才能读取密钥。
➽ 通过加密密码哈希,您可以防止字典攻击,只要密钥保密。只要攻击者在服务器上没有权限,密钥就会保密。
这与辣椒可以给您的优势相同,但与辣椒相比,加密哈希允许在必要时交换密钥。