java垃圾收集可以安全清除垃圾数据吗?

Liw*_*hao 5 java garbage-collection

这是一个内存数据安全性问题。
Java垃圾收集是否可以安全清除垃圾数据?

显然,在大块数据被垃圾回收之后,我再也无法检索它了,但是黑客仍然可以通过内存转储来检索数据吗?

And*_*gin 5

正如其他用户在这里已经提到的那样,JVM不会在垃圾回收后安全地清理内存,因为这会严重影响性能。这就是为什么许多程序(尤其是安全性库)使用可变结构而不是不可变的(char数组而不是字符串等)并在不再需要它们时清理数据本身的原因。

不幸的是,即使这样的方法也不总是可行。让我们看一下这种情况:

  1. 您使用密码创建一个char数组。
  2. JVM执行垃圾回收,并将您的char数组移动到内存中的另一个位置,保留先前被其占用的内存不变,只是将其标记为空闲块。因此,我们现在有了您的密码的“脏副本”。
  3. 您已经完成使用密码的操作,并将char数组中的所有字符显式归零,以为现在一切都已安全。
  4. 攻击者对您的内存进行转储,并在步骤2之前的第一次放置密码的内存中找到您的密码。

我只能想到一种解决此问题的方法:

  1. 使用G1垃圾收集器。
  2. 将敏感数据设置为单个块(原始值数组),该块足够大以占据G1使用的区域大小的一半以上(默认情况下,此大小取决于最大堆大小,但是您也可以手动指定它)。这将迫使收集器将您的数据视为所谓的“巨大对象”。G1 GC不会将此类对象移动到内存中。
  3. 在这种情况下,当您手动擦除块中的某些数据时,可以确保堆中某处不存在相同数据的其他“脏副本”。

另一种解决方案是使用堆外数据,您可以根据需要手动对其进行处理,但这不是纯Java。


Jim*_*mes 2

这取决于 JVM 实现以及其中可能的选项,但我认为它不会清除数据。垃圾收集只需要跟踪哪些区域可用。将所有这些数据设置为 0 或其他值会导致大量不必要的写入。正是由于这个原因,您经常会看到 API 使用字符数组而不是字符串作为密码。