我有两个https Web应用程序app1和app2安装在两个不同的tomcats t1和t2(t1和t2在不同的机器上) . 当我在app1中 Build 与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)
虽然我通过在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? 另一点是第一种和第二种方法有什么不同?
2 回答
目前尚不清楚你试图用这些选项做什么 . 您可以使用默认信任库(通常为jssecacerts, if it exists; otherwise, cacerts),也可以指定自己的信任库 .
.keystore
倾向于用作密钥库,而不是信任库(尽管没有默认的JSSE值) . (顺便说一句,我也会指定完整路径而不是C:.keystore
. )最好制作原始
cacerts
(或jssecacerts
)文件的副本(删除你更改过的额外的文件)并将远程证书添加到其中(例如,如果需要,可以复制app2 's cert in app1' s副本和app1 's cert in app2' s副本) .您可以使用
keytool -list -keystore keystore.jks
列出证书(如果需要,请参阅帮助以获取更多选项) .您可以使用
keytool -export -keystore server1-keystore.jks -alias server_alias -file server1.crt
导出证书 .然后,将其导入另一个信任库:
keytool -import -keystore client2-truststore.jks -file server1.crt
. (这里,client2-truststore.jks
将是cacerts
的副本 . )然后,配置运行Apache Tomcat(不一定是Tomcat连接器)的JVM以使用它 . 您应该能够在catalina.sh
(JAVA_OPTS=-D...
)中设置JVM参数 .EDIT:
为了更直接地回答您的问题,我只是仔细检查了干净的Oracle JRE 6安装(1.6.0_31),并且
jssecacerts
优先于cacerts
(如JSSE Ref Guide中所述,所以没有't seem to be a bug). I' m确定甲骨文已经搬到哪里安德烈亚斯·斯特本兹's Sun blog, so I'我不知道你用过哪个InstallCert
副本 . 我想我的错误就在那里 .据我所知,
InstallCert
连接到服务器以获取其证书(替换上面的导出步骤):您实际上假设您在第一次连接上获得的证书是正确的(并且可以信任) . 您也可以获得该证书using OpenSSL . 但是,在您的情况下,您似乎可以控制两个服务器及其各自的密钥库,因此您也可以使用keytool -export
来确定 .第一种方法(更改
jssecacerts
)为将使用此JRE安装的所有应用程序设置配置,而第二种方法仅在运行Apache Tomcat时将这些设置应用于JVM .请注意,如果您没有
jssecacerts
但只有cacerts
文件,如果您只将证书导入jssecacerts
,则会忽略cacerts
,因此您赢得了't be able to connect to servers that have a certificate issued by a CA that would normally be trusted by default. That'为什么从默认文件的副本开始可能会有用 . (此外,如果您的应用程序还连接到默认情况下通常可信任的其他站点,这也可以解释为什么您这次会在不同的地方收到此错误消息 . )最终,it's your responsiblity to check what's in jssecacerts or cacerts:
区别在于您将证书添加到不正确的信任库文件:) . JRE的系统信任库文件不是jssecacerts,而只是在$ / lib / security /下的cacerts . 您正在创建一个JRE不知道的新信任 . 将证书添加到正确的商店将解决您的问题 . 但是,请允许我警告您,将自定义CA证书添加到系统信任库不是一个好主意 . 将它们添加到用户信任库,并按照您在第二个选项中使用的方式使用它 .