在Java中覆盖(归零)字符串密码

在Java中覆盖(归零)字符串密码,java,java-memory-model,java-memory-leaks,Java,Java Memory Model,Java Memory Leaks,我犯了在Java程序中将密码存储为字符串的错误。我想防止此字符串密码出现在堆转储/内存转储中。理想情况下,我应该使用char[]并在使用后将其填充为零(正如本文所建议的-) 我读了一些SO帖子,了解到字符串是不可变的,它们不能被覆盖。我的问题是-没有办法用零替换已经创建的字符串的内容吗 注意:我不能改变我的实现,因为当我从一个返回字符串的模块/库中获取这个字符串时, 字符串是不可变的,简短的答案是否定的,你不能像C或C++那样用零重写同一个内存区域。您可以做的是释放对该字符串的任何引用,最终内存

我犯了在Java程序中将密码存储为字符串的错误。我想防止此字符串密码出现在堆转储/内存转储中。理想情况下,我应该使用char[]并在使用后将其填充为零(正如本文所建议的-)

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


注意:我不能改变我的实现,因为当我从一个返回字符串的模块/库中获取这个字符串时,

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

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

-XX:-UseConcMarkSweepGC
简而言之,唯一可靠的方法是首先防止内存中存在密码字符串


我为回答的错误提前表示歉意。

模块以字符串形式返回密码?如果不使用反射,您可能可以使用外部程序擦除包含字符串的内存。希望不大,但是字符串中的加扰密码可能会提供一些安全性。可能正在拦截登录的键盘事件。您可能可以使用
不安全的
,但它…不安全。我鼓励你寻找一个库,它以一种更喜欢的方式返回你的秘密,因为比起在引擎盖下闲逛组件,你会走得更远,拥有更稳定的代码,这是我们非常不想做的。我认为这不太可能,更多的是不那么简单/容易。我有一个问题。即使字符串是GCed,直到相同的内存位置被其他数据重写,字符串仍然会显示在进程级内存转储中,对吗?所以,即使保证对字符串进行垃圾收集也不会有帮助。只有归零才能防止字符串显示在内存转储中。我的理解正确吗?@MediumOne最有可能,但这可能取决于JVM的实现。