在学习Java时,我了解到字符串是not safe for storing passwords,因为你无法手动清除与它们相关的内存(你不能确定它们最终会被gc'ed,实习字符串可能永远不会,甚至在gc之后你也无法确定物理内存内容是否真的被擦除了。相反,我使用char数组,所以我可以在使用后将它们清零。我试图在其他语言和平台上搜索类似的做法,但到目前为止我找不到相关信息(通常我看到的是密码存储在字符串中的代码示例,没有提到任何安全问题)。
我对浏览器的情况特别感兴趣。我经常使用jQuery,而我通常的方法就是将密码字段的值设置为空字符串而忘记它:
$(myPasswordField).val("");
但我并不是100%确信它已经足够了。我也不知道用于中间访问的字符串是否安全(例如,当我使用$.ajax
将密码发送到服务器时)。至于其他语言,通常我没有提到这个问题(我特别感兴趣的另一种语言是Python)。
我知道尝试构建列表的问题是controversial,但由于这涉及一个很大程度上被忽视的常见安全问题,恕我直言,这是值得的。如果我弄错了,我会很高兴知道从JavaScript(在浏览器中)和Python。我也不确定是在security.SE还是在programmers.SE问这里,但由于它涉及安全执行任务的实际代码(不是概念性问题),我相信这个网站是最好的选择。
注意:在低级语言中,或明确支持字符作为基本类型的语言,答案应该是显而易见的(编辑:并不是很明显,正如@Gabe在下面的回答中所示。我要求那些“一切都是对象”或类似的高级语言,以及那些在幕后执行自动字符串实习的人(所以你可能会创建一个安全漏洞而不会意识到它,即使你'相当小心)。
更新:根据相关问题中的an answer,即使在Java中使用char[]
也不能保证防弹(或.NET SecureString,那个问题),因为gc可能会移动阵列,所以即使在清除之后它的内容也可能会粘在内存中(SecureString至少会粘在相同的RAM地址中,保证清除,但是它的消费者/生产者可能仍会留下痕迹)。 p>
我猜@NiklasB。是正确的,即使漏洞存在,漏洞的可能性很低,防止漏洞的难度很高,这可能是这个问题大多被忽视的原因。我希望我至少可以找到关于浏览器这个问题的一些参考,但谷歌搜索到目前为止一直没有结果(这种情况至少有一个名称?)。
答案 0 :(得分:4)
.NET的解决方案是SecureString
。
SecureString
对象类似于String
对象,因为它具有文本值。但是,SecureString
对象的值会自动加密,可以修改,直到您的应用程序将其标记为只读,并且可以通过您的应用程序或.NET Framework垃圾收集器从计算机内存中删除。
请注意,即使对于像C这样的低级语言,答案也不像看起来那么明显。现代编译器可以确定您正在写入字符串(将其清零)但从不读取您读出的值,只是优化掉零。为了防止优化安全性,Windows提供了SecureZeroMemory
。
答案 1 :(得分:1)
对于Python,根据this answer,没有办法做到这一点。一种可能性是使用字符列表(作为长度为1的字符串或可能是代码单元作为整数)而不是字符串,因此您可以在使用后覆盖该列表,但这需要每个触及它的代码都支持这种格式(如果是他们中的一个人创建了一个包含其内容的字符串,它已经结束了。
还有一个提到使用ctypes的方法,但link is broken,所以我不知道它的内容。 This other answer也指它,但不是很详细。