提问者:小点点

如何避免将String用于需要String的第3方库的密码或机密?


我正在开发一个Java服务,它有一个针对它的安全bug,涉及存储在JavaString对象中的秘密。

担心的是,一旦密码存储在String中,它就会一直保留在字符串池中,直到被垃圾回收,并且可能会以明文形式显示在转储中。

我理解Java的String类是不可变的,并且首选将机密或密码存储在可变类中,因此可以在使用后尽快将其从内存中删除。

参考文献

  • 为什么密码的char[]优于String?
  • Java相当于SecureString
  • 在Java中,使用char[]而不是String来存储密码还有意义吗?

然而,当使用第三方库时,我发现这是不切实际的,因为他们中的许多人希望将密码或秘密作为String对象传递给请求,无论我有多安全,在我的代码中,最终都会将char[]数组转换为String,这让我们回到了最初的问题,不是吗?

那么,是否有办法将char[]StringBuffer转换为String,而不会回到最初的问题?


共1个答案

匿名用户

如果您需要调用需要String的API,则无法避免创建String。只要您避免字符串文字或显式实习字符串,字符串就不会最终进入字符串池。

这也是一个不可能解决的问题。例如,如果这是一个数据库连接池的密码,密码需要在程序的生命周期内可用,以便能够创建新的连接。即使您可以以某种可清除的方式提供密码,如char[]CharBufferStringBuilder等,也不能保证您调用的API不会将其转换为字符串,或制作副本等。

即使使用char[]也不能保证您能够正确地从内存中清除它:Java垃圾收集器可以并且将会移动对象,因此您的密码完全有可能仍然在内存中的先前位置,即使您显式地将该char[]归零。

如果威胁参与者对您的系统有足够的访问权限来检查内存、进行堆转储等,您就会遇到更大的问题,并且担心使用Stringchar[]只是浪费时间,因为威胁参与者将有其他方法来查找您的密码,例如查找配置源、修改程序以在下一次运行时记录密码等。

明确地说,能够快速清除某些敏感信息可以减少攻击窗口,但是除非你在高安全性的环境中工作,否则考虑到所有的警告,这不太可能是正确的事情。