在运行Java进程时隐藏JKS密钥库/信任库密码

7

我有一些Java应用程序,通过SSL连接到其他应用程序和服务。在开发过程中,我可以使用JVM参数指定要使用的密钥库/信任库和密码:

-Djavax.net.ssl.trustStore=certificate.jks 
-Djavax.net.ssl.trustStorePassword=mypassword 
-Djavax.net.ssl.keyStore=certificate.jks 
-Djavax.net.ssl.keyStorePassword=mypassword 
-Djavax.net.ssl.keyStoreType=jks

这个在开发环境中是完美的。但是在生产环境中有一个隐藏密码的要求,使用JVM args意味着任何查看进程列表的人都能够清楚地看到明文密码。有没有简单的方法来解决这个问题?我考虑过将证书导入到JRE的lib/security/cacerts文件中,但我的理解是这仍然需要密码。一种选择是加密存储密码到文件中,让应用程序在运行时读取和解密,但这将涉及更改和重新发布所有应用程序(有相当多的应用程序),因此如果可能的话,我宁愿避免这种情况。javax.net.ssl库是否具有任何原生内置对加密密码的支持(即使只是如base64编码这样简单的东西,或使密码不是明文的任何内容)?任何建议都将不胜感激。
1个回答

13
首先,您可以考虑隐藏其他用户的ps输出,参见以下问题: 其次,将证书(假设含有私钥)导入到lib/security/cacerts中将毫无意义:它是默认的信任存储库,但不是默认的密钥库(没有默认值)。
第三,您实际上永远无法“加密”应用程序将使用的密码(在非交互模式下)。它必须被使用,因此如果它被加密,它的加密密钥在某个时候需要以明文形式提供。因此,这有点毫无意义。
正如您所建议的,Base 64编码只是一种编码。同样,这很毫无意义,因为任何人都可以解码它(例如,based64 -d)。像Jetty这样的一些工具可以以混淆的方式存储密码,但这并不比Base 64编码更具抵抗力。如果有人在您的肩膀上看着,它可能很有用,但仅此而已。
您可以调整应用程序从文件(以明文或混淆形式)中读取密码。您肯定需要确保未经授权的用户无法读取此文件。

真正重要的是确保 keystore 文件本身受到不应访问它的用户的保护。密码用于在其他人可以读取容器或想要在交互模式下保护访问时保护容器。由于无法避免在未经监视的机器上清晰地使用密码,因此拥有复杂密码并没有太大意义,相反,更重要的是保护文件本身。(不清楚您的应用程序是否是交互式的,但我猜测很少有用户需要交互式地输入 -Djavax.net.ssl....=... )

如果您无法调整代码以从文件中读取内容,请将您的 keystore 和密钥密码更改为您不介意披露的密码,如 "ABCD",并确保保护对此 keystore 文件的读取访问:这才是最重要的。从第二个文件中读取密码只是将问题推迟了一步,因为密码文件和 keystore 文件可能存储在一起(并被一个未经授权的人一起复制)。


同意,在某个时候、某个地方,必须存储一个密钥或密码。我想这是我们必须通过流程/用户帐户/文件权限来解决的问题。谢谢! - Matt

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