6

我有许多 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 编码一样简单,或者任何使密码不是明文的东西)?

任何建议都非常感谢。

4

1 回答 1

12

首先,您可以考虑对其他用户隐藏 ps 输出,请参阅以下问题:

其次,将您的证书(假设使用私钥)导入lib/security/cacerts是没有意义的:它是默认的信任库,但不是默认的密钥库(没有默认值)。

第三,您永远无法真正“加密”应用程序将要使用的密码(在非交互模式下)。它必须被使用,所以如果它被加密,它的加密密钥需要在某个时候以明文形式提供。因此,这有点毫无意义。

正如您所建议的,Base 64 编码只是一种编码。同样,这是毫无意义的,因为任何人都可以对其进行解码(例如based64 -d)。一些工具,如 Jetty,可以以混淆模式存储密码,但这并不比 base 64 编码更能抵抗。如果有人在你的肩膀上看着,这很有用,但就是这样。

您可以调整您的应用程序以从文件中读取密码(纯文本或混淆)。您当然需要确保未经授权的各方无法读取此文件。

真正重要的是确保密钥库文件本身受到保护,不会受到不打算阅读的用户的影响。它的密码旨在保护容器,以防其他人可以读取或您想要保护交互模式下的访问。由于您无法真正避免在无人值守模式下在机器上明文使用密码,因此设置难密码并没有什么意义,而保护文件本身更为重要。(目前尚不清楚您的应用程序是否是交互式的,但我猜应该很少有用户期望-Djavax.net.ssl....=...交互式键入。)

如果您无法调整代码以从文件中读取,请将您的密钥库和密钥密码更改为您不介意披露的密码,例如“ABCD”,并确保您保护对该密钥库文件的读取访问:这才是真正重要的到底。从辅助文件中读取密码本身只是将问题推迟了一步,因为密码文件和密钥库文件很可能彼此相邻存储(并被未经授权的一方复制在一起)。

于 2013-07-23T18:56:15.817 回答