java 查询 jvm truststore 和 jssecacerts 文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9853169/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 22:39:19  来源:igfitidea点击:

Query on jvm truststore and jssecacerts file?

javasslhttps

提问by M Sach

i have two https web applications app1 and app2 installed on two different tomcats t1 and t2(t1 and t2 are on different machines). when in app1 i make an url connection to app2 i get the SSL handshake error. The reason is i am using the self signed certificate in app2 which is not present in app1 jvm truststore. So proper approach to fix it install the self signed certificate in JAVA-HOME/jre/lib/security . To do the same , I have followed the steps given at http://www.mkyong.com/webservices/jax-ws/suncertpathbuilderexception-unable-to-find-valid-certification-path-to-requested-target/. Same steps are suggested across the different forums. But still i get the same SSL handshake error which is

我在两个不同的 tomcat t1 和 t2 上安装了两个 https Web 应用程序 app1 和 app2(t1 和 t2 在不同的机器上)。当我在 app1 中建立到 app2 的 url 连接时,我收到 SSL 握手错误。原因是我在 app2 中使用自签名证书,该证书在 app1 jvm truststore 中不存在。因此,修复它的正确方法是在 JAVA-HOME/jre/lib/security 中安装自签名证书。为了做到这一点,我遵循了http://www.mkyong.com/webservices/jax-ws/suncertpathbuilderexception-unable-to-find-valid-certification-path-to-requested-target/ 中给出的步骤。在不同的论坛中建议了相同的步骤。但我仍然收到相同的 SSL 握手错误

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path   building failed: sun.security.
provider.certpath.SunCertPathBuilderException: unable to find valid certification path to   requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)

Though it i got rid of this SSLHandshakeException by mentioning below parameters in JVM trustore. -Djavax.net.ssl.trustStore=C:.keystore -Djavax.net.ssl.trustStorePassword=changeit

虽然我通过在 JVM 信任库中提到以下参数摆脱了这个 SSLHandshakeException。-Djavax.net.ssl.trustStore=C:.keystore -Djavax.net.ssl.trustStorePassword=changeit

My question here is why first approach(which is proper approach) i.e putting the jssecacerts file under /lib/security is not working?Another point is what is different between first and second approach ?

我的问题是为什么第一种方法(这是正确的方法),即将 jssecacerts 文件放在 /lib/security 下不起作用?另一点是第一种方法和第二种方法有什么不同?

回答by Bruno

Though it i got rid of this SSLHandshakeException by mentioning below parameters in JVM trustore. -Djavax.net.ssl.trustStore=C:.keystore -Djavax.net.ssl.trustStorePassword=changeit

虽然我通过在 JVM 信任库中提到以下参数摆脱了这个 SSLHandshakeException。-Djavax.net.ssl.trustStore=C:.keystore -Djavax.net.ssl.trustStorePassword=changeit

It's not clear what you were trying to do with these options. Either you use the default truststore (normally jssecacerts, if it exists; otherwise, cacerts) or you specify your own. .keystoretends to be used as a keystore, not truststore (although there is no default JSSE value). (I would also specify the full path instead of C:.keystore, by the way.)

目前尚不清楚您尝试使用这些选项做什么。要么使用默认信任库(通常为jssecacerts,如果存在;否则为cacerts),或者指定您自己的信任库。.keystore往往用作密钥库,而不是信任库(尽管没有默认的 JSSE 值)。(C:.keystore顺便说一下,我还会指定完整路径而不是。)

It's probably better to make a copy of your original cacerts(or jssecacerts) file (remove the extra one you've put, if you've changed something) and add your remote certificate to it (i.e. app2's cert in app1's copy and app1's cert in app2's copy, if needed).

最好复制您的原始cacerts(或jssecacerts)文件(如果您更改了某些内容,请删除您放置的额外文件)并将您的远程证书添加到其中(即 app1 副本中的 app2 证书和 app2 中的 app1 证书如果需要,请复制)。

You can list the certificates using keytool -list -keystore keystore.jks(see help for more options if needed).

您可以列出使用的证书keytool -list -keystore keystore.jks(如果需要,请参阅帮助以获取更多选项)。

You can export a certificate using keytool -export -keystore server1-keystore.jks -alias server_alias -file server1.crt.

您可以使用keytool -export -keystore server1-keystore.jks -alias server_alias -file server1.crt.

Then, import it in the other truststore: keytool -import -keystore client2-truststore.jks -file server1.crt. (Here, client2-truststore.jkswill be a copy of cacerts.) Then, configure your JVM running Apache Tomcat (not necessarily the Tomcat connector) to use it. You should be able to set the JVM parameters in catalina.sh(JAVA_OPTS=-D...).

然后,将其导入另一个信任库:keytool -import -keystore client2-truststore.jks -file server1.crt。(这里client2-truststore.jks是 的副本cacerts。)然后,配置运行 Apache Tomcat(不一定是 Tomcat 连接器)的 JVM 以使用它。您应该能够在catalina.sh( JAVA_OPTS=-D...) 中设置 JVM 参数。

EDIT:

编辑:

My question here is why first approach(which is proper approach) i.e putting the jssecacerts file under /lib/security is not working?

我的问题是为什么第一种方法(这是正确的方法),即将 jssecacerts 文件放在 /lib/security 下不起作用?

To answer your question more directly, I've just double-checked on a clean Oracle JRE 6 installation (1.6.0_31), and jssecacertstakes precedence over cacertswhen present (as documented in the JSSE Ref Guide, so there doesn't seem to be a bug). I'm not sure where Oracle have moved Andreas Sterbenz's Sun blog, so I'm not sure which copy of InstallCertyou've used. I guess something my have gone wrong there.

为了更直接地回答您的问题,我刚刚仔细检查了干净的 Oracle JRE 6 安装 (1.6.0_31),并在存在时jssecacerts优先cacerts(如 JSSE 参考指南中所述,因此似乎没有一个错误)。我不确定 Oracle 将 Andreas Sterbenz 的 Sun 博客移到何处,因此我不确定InstallCert您使用了哪个副本。我想我在那里出了问题。

As far as I'm aware, InstallCertconnects to the server to get its certificate (replacing the export step above): you effectively assume that the certificate you get on your first connection is the right one (and can be trusted). You could also get that certificate using OpenSSL. However, in your case, you seem to have control over the two servers and their respective keystores, so you might as well use keytool -exportto be sure.

据我所知,InstallCert连接到服务器以获取其证书(替换上面的导出步骤):您实际上假设您在第一次连接时获得的证书是正确的(并且可以信任)。您还可以使用 OpenSSL获取该证书。但是,在您的情况下,您似乎可以控制两台服务器及其各自的密钥库,因此您不妨keytool -export确定一下。

Another point is what is different between first and second approach ?

另一点是第一种方法和第二种方法有什么不同?

The first approach (changing jssecacerts) sets the configuration for all applications that will use this installation of the JRE, whereas the second will apply those settings to the JVM once it's running Apache Tomcat only.

第一种方法(更改jssecacerts)为将使用此 JRE 安装的所有应用程序设置配置,而第二种方法将在 JVM 仅运行 Apache Tomcat 时将这些设置应用到 JVM。

Note, that if you didn't have a jssecacertsbut only a cacertsfile, if you only import your certificate into jssecacerts, cacertswill be ignored, so you won't be able to connect to servers that have a certificate issued by a CA that would normally be trusted by default. That's why starting with a copy of the default file can be useful. (In addition, if your application also connects to other sites that would normally be trusted by default, this could also explain why you'd get this error message, at a different place this time.)

请注意,如果您没有jssecacerts但只有一个cacerts文件,如果您只将证书导入jssecacerts,cacerts将被忽略,因此您将无法连接到具有由 CA 颁发的证书的服务器,通常情况下默认信任。这就是为什么从默认文件的副本开始会很有用的原因。(此外,如果您的应用程序还连接到默认情况下通常受信任的其他站点,这也可以解释为什么您会在这次不同的位置收到此错误消息。)

Ultimately, it's your responsiblity to check what's in jssecacertsor cacerts:

最终,您有责任检查jssecacertscacerts

IMPORTANT NOTE: The JDK ships with a limited number of trusted root certificates in the /lib/security/cacerts file. As documented in keytool, it is your responsibility to maintain (that is, add/remove) the certificates contained in this file if you use this file as a truststore.

Depending on the certificate configuration of the servers you contact, you may need to add additional root certificate(s). Obtain the needed specific root certificate(s) from the appropriate vendor.

重要说明:JDK 在 /lib/security/cacerts 文件中附带有限数量的受信任根证书。如 keytool 中所述,如果您将此文件用作信任库,则您有责任维护(即添加/删除)此文件中包含的证书。

根据您联系的服务器的证书配置,您可能需要添加额外的根证书。从适当的供应商处获取所需的特定根证书。

回答by Drona

The difference is that you added the certificate to the incorrect truststore file :). JRE's system truststore file is not jssecacerts but simply cacerts under ${JRE_HOME}/lib/security/. You were creating a new trustore which the JRE isn't aware of. Adding the certificate to the proper store will resolve your problem. However, let me warn you that it is not a good idea to add your custom CA certificates to the system truststore. Add them to the user truststore and use it the way you are using in the second option.

不同之处在于您将证书添加到了不正确的信任库文件 :)。JRE 的系统信任库文件不是 jssecacerts 而是 ${JRE_HOME}/lib/security/ 下的 cacerts。您正在创建一个 JRE 不知道的新委托人。将证书添加到正确的存储将解决您的问题。但是,让我警告您,将您的自定义 CA 证书添加到系统信任库并不是一个好主意。将它们添加到用户信任库并按照您在第二个选项中使用的方式使用它。