【问题标题】:Sensitive data in java heap dumpsJava 堆转储中的敏感数据
【发布时间】:2011-07-25 20:19:48
【问题描述】:

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

当我们遇到内存问题时,最好让应用程序编写一个堆转储。问题是,如果线程恰好在该区域中工作,堆转储可能包含纯文本形式的敏感信息......当我们费尽心思在其他地方加密它时,我们真的不希望将这些信息写入磁盘。

有没有办法解决这个问题,比如让 JVM 写一个加密转储?

【问题讨论】:

  • 哇,我有兴趣看看是否有解决方案——这既昂贵又蹩脚,但要加密对象中的所有内容
  • 任何具有 root 访问权限的人都可以获取转储和/或修改应用程序。所以,我看不出加密任何东西的理由。您可以使用任何 java 进程的 jmap 获取堆转储。
  • 您可以与任何可能查看堆转储的人签署 NDA 和安全协议...只是想在这里集思广益。

标签: java encryption passwords heap-memory


【解决方案1】:

我一直在考虑在虚拟机之外处理这个问题。一种天真的方法可能是让 jvm 将转储写入加密的环回设备。当然,这并不完全安全,因为任何具有 root 访问权限的人都可以到达挂载点,但这是我所期待的那种解决方案。我可能会看看是否可以设置 jvm 最终写入的 FIFO。我知道 vm 将使用的文件名,所以这可能取决于 vm 如何处理它(后来:这不起作用。JVM 抱怨“文件存在”)

使用 char 数组只能缓解这个问题,但数组在转储时仍有可能包含一些纯文本。

【讨论】:

  • 如果您要注册,您就可以让代表进入一个帐户。
  • 即使你这样做了,数据在某个时间点仍然作为托管堆对象存在。我不确定降低风险的收益递减点在哪里。
【解决方案2】:

简短的回答并不完全。在某些时候,您必须明确数据才能使用它,并且在垃圾收集的 VM 中,您无法控制何时从内存中物理删除对象。将风险降至最低的唯一真正策略是尽快删除对未加密机密数据的所有引用。它不能保证不会将机密数据写入内存转储中,但如果有人能做到这一点,那么他们已经可以获取关键信息。

【讨论】:

  • 但是在取消引用之前一定要核对内存区域! (因此,切勿将密码存储在 String 对象中,而应使用 char[]。)
  • 在相关说明中,我过去需要做一些事情,比如接受用户的密码,然后将其传递给 WS 调用,但 JAXB 无法使用字节数组来传递一个字符串值。有谁知道解决这个问题的方法吗?
  • @Chris,java 中的“nuking”内存不起作用。垃圾收集器可以随时随意复制内容,因此您将留下一个非核对象。您唯一能做的就是使用 DirectCharacterBuffers,而不是 char[],只需使用一个大缓冲区并将其切片,因为直接缓冲区至少占用内存中的一页。更糟糕的是,你必须清除所有的痕迹,包括套接字缓冲区。总的来说,这是一项毫无价值的努力。
  • @Chris,该 jit 可能足以将大多数表单从“nuking”优化为无操作。如果有办法在程序中隐藏这类数据,它就会被用来创建工作软件 DRM/Copyprotection。
【解决方案3】:

Paypal 最近发布了一个工具,用于从堆转储中删除敏感数据:

https://github.com/paypal/heap-dump-tool

【讨论】:

    猜你喜欢
    • 2017-09-05
    • 2020-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-27
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    相关资源
    最近更新 更多