2

我犯了将密码存储为 Java 程序中的字符串的错误。我想防止这个字符串密码出现在堆转储/内存转储中。理想情况下,我应该使用 char[] 并在使用后将其填充为零(如本文所推荐 - https://nvisium.com/resources/blog/2016/03/31/secure-password-strings.html) .

我阅读了一些 SO 帖子并了解字符串是不可变的,它们不能被覆盖。我的问题是 - 有没有办法用零替换已经创建的字符串的内容?

注意:我现在无法将实现更改为使用 char[],因为我从返回字符串的模块/库中获取此字符串。

4

1 回答 1

1

由于字符串是不可变的,简短的回答是否定的,您不能像在 C 或 C++ 中那样用零覆盖相同的内存区域。您可以做的是释放对该字符串的任何引用,最终内存空间将从堆中释放,并且不会出现在堆转储中。问题是 GC 的时间变化很大,并且不受您的控制。

您可以要求系统进行 GC,但这并不能保证它会这样做。这更像是一个提示。此外,即使应该发生 GC,根据您的提示或主动发生,也不能保证在任何特定的 GC 运行期间都会收集字符串。这种行为不仅在 JVM 版本之间存在差异,而且在可能使用不同 GC 方案的 JVM 版本中也存在差异。您可以在命令行上设置方案作为示例:

-XX:-UseConcMarkSweepGC

简而言之,唯一可靠的方法是从一开始就防止密码字符串存在于内存中。

对于答案的无赖,我提前道歉。

于 2018-02-16T15:27:39.387 回答