2016-07-29 167 views
3

这是一个内存数据安全问题。
Java垃圾收集是否安全地清理垃圾数据?java垃圾收集是否安全地清除垃圾数据?

后显然的数据块进行垃圾收集,我无法恢复了,但黑客仍然内存转储检索数据?

+0

相关:http://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords-in-java – shmosel

+0

内存安全很难做到。 同样,当有人闯入您的手机以扫描内存中的数据时,他们几乎可以从手机获取大部分安全信息。 努力可以更好地保护存储和传输过程中的数据。 –

+0

这是我担心的HIPAA合规性问题。不确定HIPAA Compliance是否需要内存加密。 –

回答

2

这依赖于JVM实现和可能的选项之内,但我认为它不会清除数据。垃圾收集只需跟踪哪些区域可用。将所有这些数据设置为0或其他东西是很多不必要的写入。正因如此,您经常会看到API使用char数组来获取密码而不是字符串。

+0

值得一提的是,char数组只会降低攻击成功的概率,但不能保证其完全消除。 –

+0

@AndrewLygin对。我也没有提到你需要自己清理阵列。数组无法避免从内存转储中读取内容。 – JimmyJames

+0

不幸的是,这里的情况稍微复杂一些,甚至手工清理数据并不总是能够完全摆脱它们。详情请参阅我的回答。 –

0

具体甲骨文JVM不会清除空间,只伊甸园和Survivor空间,不再仅仅使用呆在那里作为最终将覆盖一个垃圾对象之间复制数据。类似的事情发生在OldGen中,有些地方被标记为已使用,并且当对象符合垃圾回收的条件时,它占用的位置被标记为未使用。在给定足够的应用时间的情况下,它也会被重写。

+0

Oracle JVM是典型的Java VM吗? 我更关心Android应用数据安全。 –

+0

@李文钊Android(或者说Dalvik/ART)不是JVM,所以你不能在JVM上应用任何东西。请用'android'注释你的问题。 Oracle是JVM的参考实现。 –

4

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

不幸的是,即使这样的方法并不总是奏效。让我们来看看这种情况:

  1. 您使用密码创建了一个char数组。
  2. JVM执行垃圾回收并将char数组移动到内存中的另一个位置,使之前占用的内存保持不变,只是将其标记为空闲块。所以,我们现在有一个密码的“脏拷贝”。
  3. 你已经完成了你的密码工作,并明确地清零你的char数组中的所有字符,并认为现在一切都安全了。
  4. 攻击使你的内存转储,并在它被放置在第一时间内存找到您的密码,步骤2

我能想到的唯一一个针对此问题可能的解决方案之前:

  1. 使用G1垃圾回收器。
  2. 让您的敏感数据的单块(原始值的阵列)足够大,它占用了区域大小的一半以上,由G1使用(默认情况下,这个大小取决于最大堆大小,但你也可以手动指定)。这会迫使收藏家将您的数据视为所谓的“大型对象”。 G1 GC不会将这些对象移动到内存中。
  3. 在这种情况下,当你手动删除在块的一些数据,可以肯定的是,相同的数据的其他“脏副本”在某处堆存在。

另一个解决方案是使用您可以手动处理的堆外数据,但不会是纯Java。

+0

在Go中,您可以使用syscalls直接从内核(mmap/virtualalloc等)使用纯Go请求内存。不确定在Java中是否可能有类似的东西。 – Awn