【问题标题】:GuardedString and memory persistence with the JVMJVM 的 GuardedString 和内存持久性
【发布时间】:2023-03-14 18:51:02
【问题描述】:

上下文

我最近参加了一场密码学讲座,我们讨论了关键元素在内存中的持久性。通常,C/C++ 库 Libsodium 建议清除任何包含敏感信息的缓冲区,例如机密 (ref)。我知道GuardedString 由字节数组支持,文档建议在不再使用存储的秘密后调用方法dispose,使用Arrays.fill 填充字节数组。

问题

JVM 是否保证字节数组的值在被覆盖时会消失,或者在某些条件下原始值是否会保留在内存中?例如,未使用/未引用的Strings 保存在 Java 字符串池 中,直到触发垃圾回收。是否有类似的 缓存 或其他类型的机制,例如可以破坏应该从 GuardedString 处理的秘密的字节数组? JVM规范中的任何参考?

非常感谢!

【问题讨论】:

  • 例如见stackoverflow.com/a/121798/1531124。理论上,将空值写入数组应该已经足够了。
  • JVM 是否保证... 不,JVM 还没有实现那种安全内存。
  • @GhostCat 理论上,JVM 可以消除任何从不跟随读取的写入,即对之后放弃的对象进行的写入。此外,由于复制垃圾收集器,未知数量的副本可能已经在堆内存中飞来飞去。 在实践中,即使没有真正的保证,这种零填充可能已经足够了。
  • @ZenLulz 字符串池在这里无关紧要。密码字符串不会进入池中,除非您明确输入(通常不会这样做)。但无论它是否在池中,所有对象都保留在内存中,直到触发垃圾回收。即使在垃圾回收之后,它们的内容也可能会在内存中保留一段未知的时间,直到它被覆盖以重新使用该特定内存的实际新分配。
  • @GhostCat 我指的是通常尝试在您知道以后根本不会使用该数组的地方用零填充数组。在这种情况下,JVM 不太可能检测到这是对象的最后一次使用,因此写入已过时。原则上,JVM 可以消除 任何 内存访问,只要它可以确保读取被先前写入的值正确替换,就像在逃逸分析之后发生的那样。但是当然,如​​果密码根本没有写入内存,我们就没有问题。

标签: java cryptography jvm internals


【解决方案1】:

在 Java 中,通常会使用 char[] 数组而不是 String,因为这允许手动将数组中的数据归零。

但是即使这样,数据也可能不会按照this answer 完全取消设置:

如 cmets 中所述,被垃圾收集器移动的数组可能会将数据的杂散副本留在内存中。我相信这是特定于实现的 - 垃圾收集器可能会随时清除所有内存,以避免这种事情。即使是这样,char[] 仍然有一段时间包含实际字符作为攻击窗口。

如果编译器决定优化memset,C/C++ 中也存在类似问题。根据11.4. Specially Protect Secrets (Passwords and Keys) in User Memory

Andy Polyakov 的一篇 Bugtraq 帖子(2002 年 11 月 7 日)报告说,C/C++ 编译器 gcc 版本 3 或更高版本、SGI MIPSpro 和 Microsoft 编译器消除了对 memset 的简单内联调用,以覆盖机密。这是 C 和 C++ 标准所允许的。其他 C/C++ 编译器(例如低于版本 3 的 gcc)在所有优化级别保留了对 memset 的内联调用,这表明该问题是特定于编译器的。简单地声明目标数据是 volatile 对所有编译器都没有帮助; MIPSpro 和 Microsoft 编译器都忽略了简单的“挥发”。简单地“触摸”秘密数据的第一个字节也无济于事;他发现 MIPSpro 和 GCC>=3 巧妙地仅使第一个字节无效,而将其余字节保持不变(这实际上非常聪明 - 问题在于编译器的聪明才智干扰了我们的目标)。

【讨论】:

  • 嘿@Karol Dowbecki。感谢您的回答。我想知道是否使用pinned memory(例如ByteBuffer.allocateDirect)或直接使用对象Unsafe可以解决这种情况。
  • 换句话说,没有。
  • @ZenLulz 仅此一项并不能解决问题,但确实可以,a) 避免内存中的多个副本,b) 避免在堆转储或调试会话中可见,c) 容易,但不完全可靠,被覆盖。
猜你喜欢
  • 1970-01-01
  • 2017-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-23
  • 1970-01-01
  • 2013-07-17
相关资源
最近更新 更多