java“PKIX路径构建失败”和“无法找到请求目标的有效证书路径”
我正在尝试使用twitter4j库为我的java项目获取推文,该项目使用UndertheCoversjava.net.HttpURLConnection
(如StackTrace中所示)。在第一次运行时,我得到一个关于证书sun.security.validator.ValidatorException
和sun.security.provider.certpath.SunCertPathBuilderException
的错误。然后,我通过以下方式添加了twitter证书:
C:\Program Files\Java\jdk1.7.0_45\jre\lib\security>keytool -importcert -trustcacerts -file PathToCert -alias ca_alias -keystore "C:\Program Files\Java\jdk1.7.0_45\jre\lib\security\cacerts"
但是没有成功。以下是获取推文的过程:
public static void main(String[] args) throws TwitterException {
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey("myConsumerKey")
.setOAuthConsumerSecret("myConsumerSecret")
.setOAuthAccessToken("myAccessToken")
.setOAuthAccessTokenSecret("myAccessTokenSecret");
TwitterFactory tf = new TwitterFactory(cb.build());
Twitter twitter = tf.getInstance();
try {
Query query = new Query("iphone");
QueryResult result;
result = twitter.search(query);
System.out.println("Total amount of tweets: " + result.getTweets().size());
List<Status> tweets = result.getTweets();
for (Status tweet : tweets) {
System.out.println("@" + tweet.getUser().getScreenName() + " : " + tweet.getText());
}
} catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to search tweets: " + te.getMessage());
}
下面是错误:
sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
Relevant discussions can be found on the Internet at:
http://www.google.co.jp/search?q=d35baff5 or
http://www.google.co.jp/search?q=1446302e
TwitterException{exceptionCode=[d35baff5-1446302e 43208640-747fd158 43208640-747fd158 43208640-747fd158], statusCode=-1, message=null, code=-1, retryAfter=-1, rateLimitStatus=null, version=3.0.5}
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:177)
at twitter4j.internal.http.HttpClientWrapper.request(HttpClientWrapper.java:61)
at twitter4j.internal.http.HttpClientWrapper.get(HttpClientWrapper.java:81)
at twitter4j.TwitterImpl.get(TwitterImpl.java:1929)
at twitter4j.TwitterImpl.search(TwitterImpl.java:306)
at jku.cc.servlets.TweetsAnalyzer.main(TweetsAnalyzer.java:38)
Caused by: 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 sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at java.net.HttpURLConnection.getResponseCode(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
at twitter4j.internal.http.HttpResponseImpl.<init>(HttpResponseImpl.java:34)
at twitter4j.internal.http.HttpClientImpl.request(HttpClientImpl.java:141)
... 5 more
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.validate(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 20 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 26 more
Failed to search tweets: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
# 1 楼答案
"more info" > "security" > "show certificate" > "details" > "export.."
。选择名称并选择文件类型示例。cer现在您有了带有密钥库的文件,您必须将其添加到JVM中。确定cacerts文件的位置,例如。
C:\Program Files (x86)\Java\jre1.6.0_22\lib\security\cacerts.
接下来将
example.cer
文件导入命令行中的cacerts(可能需要管理员命令提示):keytool -import -alias example -keystore "C:\Program Files (x86)\Java\jre1.6.0_22\lib\security\cacerts" -file example.cer
您将被要求输入默认为
changeit
的密码重新启动JVM/PC
资料来源: http://magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed.html
# 2 楼答案
它用于跳转证书验证
警告 仅用于开发目的,因为这是不安全的
# 3 楼答案
我的UI方法:
命令行:
keytool -importcert -file jetty.crt -alias jetty -keystore $JAVA_HOME/jre/lib/security/cacerts
changeit
(可以是Mac上的changeme)# 4 楼答案
一,。检查证书
尝试在浏览器中加载目标URL并查看站点的证书(通常可以通过带有锁定标志的图标访问。它位于浏览器地址栏的左侧或右侧),无论该证书是否已过期或因其他原因不受信任
二,。安装最新版本的JRE和JDK
新版本通常附带一组更新的可信证书
如果可能的话,卸载旧版本。这将明确错误配置错误
三,。检查您的配置:
四,。从新Java版本复制整个密钥库
如果您在JDK下开发的不是最新的可用文件,请尝试用最新安装的JRE中的新文件替换
%JAVA_HOME%/jre/lib/security/cacerts
文件(首先制作备份副本),正如@jeremy goodell在他的answer中所建议的那样五,。将证书添加到密钥库
如果上面的任何内容都不能解决您的问题,请使用
keytool
将证书保存到Java的密钥库:如@maggg在他的answer中建议的那样,可以从浏览器中获取带有证书的文件
注1:您可能需要对站点证书链中的每个证书重复此操作。从根开始
注2:
<alias_name>
在存储区中的键之间应该是唯一的,否则keytool
将显示错误要获取存储区中所有证书的列表,您可以运行:
如果出现问题,这将帮助您从存储中删除证书:
# 5 楼答案
为了让我的Java 6安装能够使用新的twitter证书,我花了好几个小时试图构建证书文件,最后我在一个留言板的评论中偶然发现了一个非常简单的解决方案。只需从Java7安装中复制cacerts文件,并覆盖Java6安装中的文件。也许最好先备份cacerts文件,但你只需将新文件复制进来,就可以了!它只是工作
请注意,我实际上是将一个WindowsCacerts文件复制到Linux安装中的,它工作得很好
在旧的和新的JavaJDK安装中,该文件都位于
jre/lib/security/cacerts
希望这能帮别人省下几个小时的烦恼
# 6 楼答案
我偶然发现这个问题,花了很多小时的研究来解决,特别是自动生成的证书,与官方证书不同,它非常棘手,Java不太喜欢它们
请检查以下链接:Solve Problem with certificates in Java
基本上,您必须将服务器上的证书添加到Java主证书中
InstallCert
的Java源代码,并在服务器运行时执行它,提供以下参数server[:port]
。不需要密码,因为原始密码适用于Java证书(“changeit”)李>jssecerts
文件(如果从Eclipse执行,请确保在Run -> Configurations
中配置工作目录)李>$JAVA_HOME/jre/lib/security
遵循这些步骤后,与证书的连接将不再在Java中生成异常
下面的源代码很重要,它从(Sun)Oracle博客中消失了,我发现它的唯一一个页面是在提供的链接上,因此我将其附在答案中以供参考