Java堆转储中的敏感数据

7

我编写的软件处理各种敏感信息,例如电子邮件地址、密码和信用卡号码。

当我们遇到内存问题时,最好让应用程序写入堆转储。但问题是,如果某个线程正在该区域工作,则堆转储可能包含明文的敏感信息... 我们不希望在我们在其他地方进行加密的情况下将其写入磁盘。

有没有方法来处理这种情况,例如导致JVM编写加密的转储?


哇,我很想看看是否有一个解决方案 - 这很昂贵和糟糕,但加密你的所有对象。 - somid3
1
任何拥有 root 访问权限的人都可以获取 dump 文件并/或修改应用程序。因此,我不太认为有必要加密任何内容。您可以使用 jmap 获取任何 Java 进程的堆 dump。 - bestsss
你可以与任何可能查看堆转储的人签署NDA和安全协议... 我只是在尝试头脑风暴。 - devinbost
3个回答

4
我一直在考虑在虚拟机外处理这个问题。一个天真的方法可能是让JVM将转储写入加密的回环设备中。当然,这并不是完全安全的,因为任何具有root访问权限的人都可以访问挂载点,但这是我期望的解决方案。我可能会尝试设置一个FIFO,让JVM最终写入其中。我知道虚拟机将使用的文件名,所以这可能会起作用,具体取决于虚拟机如何处理(后来:这不起作用。JVM抱怨“文件已存在”)。
仅使用字符数组只能缓解问题,但在转储时仍有可能包含某些明文。

1
如果您注册了,就可以将声望添加到一个账户上。 - Daniel
即使这样做,数据在某个时间点仍然作为托管堆对象存在。我不确定在风险降低方面的收益递减点在哪里。 - Jeremy

2

简短的回答是不完全。在某些时候,您必须将数据明文使用,并且在垃圾收集的虚拟机中,您无法控制对象何时从内存中物理删除。唯一真正的策略是尽快删除所有对未加密机密数据的引用,以最大程度地减少风险。这并不能保证没有机密数据会被写入内存转储,但如果有人能够这样做,那么他们已经可以获得关键信息。


4
在取消引用之前,务必对内存区域进行清空!因此,永远不要将密码存储在“String”对象中,而是使用“char []”。 - C. K. Young
顺便提一下,我以前需要做的事情之一是接受用户的密码,然后将其传递给WS调用,但JAXB没有使用字节数组来传递字符串值的方法。有人知道解决这个问题的方法吗? - Steve Jorgensen
1
@Chris,“nuking”内存在Java中是无效的。垃圾收集器可以随时复制内容,因此您将得到一个未被“nuked”的对象。您唯一能做的就是使用DirectCharacterBuffers,而不是char[],只需使用一个大缓冲区并对其进行切片,因为直接缓冲区至少需要一页内存。更糟糕的是,您必须清除所有包括套接字缓冲区在内的痕迹。总体而言,这是一项毫无价值的努力。 - bestsss
@Chris,JIT 可能足够优化大多数形式的“nuking”为无操作。如果有一种方法可以隐藏这种数据在程序中,它将被用于创建工作软件 DRM/副本保护。 - josefx

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接