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

标签 java java-memory-model java-memory-leaks

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

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

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

最佳答案

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

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

-XX:-UseConcMarkSweepGC

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

我提前为回答的无礼道歉。

关于java - 在 Java 中覆盖(归零)字符串密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48829440/

相关文章:

java - Gradle 插件与 AutoValue 和 FreeBuilder 混淆/冲突

java - 使用synchronized时寄存器刷新如何工作?

Java:保证非最终引用字段永远不会被读取为空的正确方法是什么?

android - Jetpack Compose 中的 LazyList 内存泄漏

java.lang.OutOfMemory错误: Java heap space (JUnit test)

java - 在 java restful api 中查找内存泄漏

java - String charAt() 方法在 Java 中如何工作?

java - libGdx getWorldHeight 返回错误值

java - 如何在java中获取之前的时间

java - 为什么要定义Java内存模型?