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

Mat*_*att 5 ssl keystore ssl-certificate truststore

我有许多Java应用程序通过SSL保护的连接连接到其他应用程序和服务.在开发期间,我可以使用JVM args指定要使用的密钥库/信任库和密码:

-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
Run Code Online (Sandbox Code Playgroud)

这非常有效.但是,在进入生产环境时需要隐藏密码,使用JVM args意味着任何查看进程列表的人都能够以明文形式查看密码.

有一种简单的方法来解决这个问题吗?我考虑将证书导入JRE的lib/security/cacerts文件,但我的理解是这仍然需要密码.一种选择是将密码(加密)存储在一个文件中,然后让应用程序即时读取和解密,但这将涉及更改和重新释放所有应用程序(其中有相当多),所以我如果可能的话,宁愿避免这种情况.javax.net.ssl库是否具有对加密密码的任何本机内置支持(即使它只是像base64encoding那样简单,或者任何使密码不清晰的文本)?

任何建议非常感谢.

Bru*_*uno 9

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

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

第三,您永远不能真正"加密"应用程序将要使用的密码(在非交互模式下).必须使用它,因此如果它被加密,则需要在某些时候清楚地提供其加密密钥.因此,这有点无意义.

正如您所建议的,Base 64编码只是一种编码.再一次,它是毫无意义的,因为任何人都可以解码它(例如based64 -d).一些工具,如Jetty,可以以混淆模式存储密码,但这并不比基本64编码更耐用.如果有人正在看你的肩膀,这是有用的,但就是这样.

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

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

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