“PKIXpathbuild立失败”和“无法find有效的证书path到请求的目标”
我正在尝试使用twitter4j库为我的Java项目鸣叫。 在我第一次运行时,我得到了关于证书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"
但没有成功。 这里是获取twitters的程序:
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
-
转到您的Firefox浏览器的URL,点击HTTPS证书链(在URL地址旁边)。 点击
"more info" > "security" > "show certificate" > "details" > "export.."
。 拾取名称并select文件typesexample.cer。 现在你有了keystore的文件,你必须把它添加到你的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
你会被要求input密码,默认为changeit
重新启动您的JVM / PC。
来源: http : //magicmonster.com/kb/prg/java/ssl/pkix_path_building_failed.html
经过几个小时的努力build立证书文件以使我的Java 6安装与新的twitter证书一起工作之后,我终于偶然发现了一个令人难以置信的简单的解决scheme,它埋在了一个留言板的评论中。 从Java 7安装中复制cacerts文件,并覆盖Java 6安装中的一个。 可能最好先备份cacerts文件,但是你只需复制新文件和BOOM! 它只是工作。
请注意,我实际上复制了一个Windows cacerts文件到Linux安装,它工作得很好。
该文件位于jre/lib/security/cacerts
中,在旧的和新的Java jdk安装中。
希望这可以节省别人几个小时的加重。
我偶然发现了这个需要花费数小时的时间研究才能解决的问题,特别是自动生成的证书,与官方的证书不同,这个问题非常棘手,而Java并不太喜欢它们。
请检查以下链接: 解决Java中的证书问题
基本上你必须从服务器添加证书到Java Home证书。
- 生成或获取证书并configurationTomcat以在Servers.xml中使用它
- 下载
InstallCert
类的Java源代码,并在服务器运行时执行它,提供以下参数server[:port]
。 由于原始密码适用于Java证书(“changeit”),因此不需要密码。 - 本程序将连接到服务器,Java将抛出一个exception,它将分析服务器提供的证书,并允许您在执行本程序的目录内创build一个
jssecerts
文件(如果从Eclipse执行,请确保configuration工作目录在Run -> Configurations
)。 - 手动将该文件复制到
$JAVA_HOME/jre/lib/security
遵循这些步骤之后,与证书的连接不会在Java中再生成exception。
以下源代码非常重要,它从(Sun)Oracle博客中消失了,我发现它的唯一页面位于所提供的链接上,因此我将其附加在任何参考的答案中。
/* * Copyright 2006 Sun Microsystems, Inc. All Rights Reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * - Neither the name of Sun Microsystems nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** * Originally from: * http://blogs.sun.com/andreas/resource/InstallCert.java * Use: * java InstallCert hostname * Example: *% java InstallCert ecc.fedora.redhat.com */ import javax.net.ssl.*; import java.io.*; import java.security.KeyStore; import java.security.MessageDigest; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; /** * Class used to add the server's certificate to the KeyStore * with your trusted certificates. */ public class InstallCert { public static void main(String[] args) throws Exception { String host; int port; char[] passphrase; if ((args.length == 1) || (args.length == 2)) { String[] c = args[0].split(":"); host = c[0]; port = (c.length == 1) ? 443 : Integer.parseInt(c[1]); String p = (args.length == 1) ? "changeit" : args[1]; passphrase = p.toCharArray(); } else { System.out.println("Usage: java InstallCert [:port] [passphrase]"); return; } File file = new File("jssecacerts"); if (file.isFile() == false) { char SEP = File.separatorChar; File dir = new File(System.getProperty("java.home") + SEP + "lib" + SEP + "security"); file = new File(dir, "jssecacerts"); if (file.isFile() == false) { file = new File(dir, "cacerts"); } } System.out.println("Loading KeyStore " + file + "..."); InputStream in = new FileInputStream(file); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(in, passphrase); in.close(); SSLContext context = SSLContext.getInstance("TLS"); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); X509TrustManager defaultTrustManager = (X509TrustManager) tmf.getTrustManagers()[0]; SavingTrustManager tm = new SavingTrustManager(defaultTrustManager); context.init(null, new TrustManager[]{tm}, null); SSLSocketFactory factory = context.getSocketFactory(); System.out.println("Opening connection to " + host + ":" + port + "..."); SSLSocket socket = (SSLSocket) factory.createSocket(host, port); socket.setSoTimeout(10000); try { System.out.println("Starting SSL handshake..."); socket.startHandshake(); socket.close(); System.out.println(); System.out.println("No errors, certificate is already trusted"); } catch (SSLException e) { System.out.println(); e.printStackTrace(System.out); } X509Certificate[] chain = tm.chain; if (chain == null) { System.out.println("Could not obtain server certificate chain"); return; } BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); System.out.println(); System.out.println("Server sent " + chain.length + " certificate(s):"); System.out.println(); MessageDigest sha1 = MessageDigest.getInstance("SHA1"); MessageDigest md5 = MessageDigest.getInstance("MD5"); for (int i = 0; i < chain.length; i++) { X509Certificate cert = chain[i]; System.out.println (" " + (i + 1) + " Subject " + cert.getSubjectDN()); System.out.println(" Issuer " + cert.getIssuerDN()); sha1.update(cert.getEncoded()); System.out.println(" sha1 " + toHexString(sha1.digest())); md5.update(cert.getEncoded()); System.out.println(" md5 " + toHexString(md5.digest())); System.out.println(); } System.out.println("Enter certificate to add to trusted keystore or 'q' to quit: [1]"); String line = reader.readLine().trim(); int k; try { k = (line.length() == 0) ? 0 : Integer.parseInt(line) - 1; } catch (NumberFormatException e) { System.out.println("KeyStore not changed"); return; } X509Certificate cert = chain[k]; String alias = host + "-" + (k + 1); ks.setCertificateEntry(alias, cert); OutputStream out = new FileOutputStream("jssecacerts"); ks.store(out, passphrase); out.close(); System.out.println(); System.out.println(cert); System.out.println(); System.out.println ("Added certificate to keystore 'jssecacerts' using alias '" + alias + "'"); } private static final char[] HEXDIGITS = "0123456789abcdef".toCharArray(); private static String toHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(bytes.length * 3); for (int b : bytes) { b &= 0xff; sb.append(HEXDIGITS[b >> 4]); sb.append(HEXDIGITS[b & 15]); sb.append(' '); } return sb.toString(); } private static class SavingTrustManager implements X509TrustManager { private final X509TrustManager tm; private X509Certificate[] chain; SavingTrustManager(X509TrustManager tm) { this.tm = tm; } public X509Certificate[] getAcceptedIssuers() { throw new UnsupportedOperationException(); } public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { throw new UnsupportedOperationException(); } public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { this.chain = chain; tm.checkServerTrusted(chain, authType); } } }
-Dmaven.wagon.http.ssl.insecure=true -Dmaven.wagon.http.ssl.allowall=true
它用于跳转证书validation。
我的UI方法:
- 下载http://www.keystore-explorer.org/
- 打开$ JAVA_HOME / jre / lib / security / cacerts
- inputPW:changeit(可以在Mac上改变)
- 导入您的.crt文件
CMD线:
- keytool -importcert -file jetty.crt -alias jetty -keystore $ JAVA_HOME / jre / lib / security / cacerts
- inputPW:changeit(可以在Mac上改变)
当我的系统上同时存在JDK和JRE 1.8.0_112时,情况稍有不同。
我使用已知的命令将新的CA证书导入到[JDK_FOLDER]\jre\lib\security\cacerts
:
keytool -import -trustcacerts -keystore cacerts -alias <new_ca_alias> -file <path_to_ca_cert_file>
不过,我不断得到相同的PKIXpathbuild设失败的错误。
我通过使用java -Djavax.net.debug=all ... > debug.log
将debugging信息添加到java CLI。 在debug.log文件中,以trustStore开头的行是:实际上指向[JRE_FOLDER]\lib\security\cacerts
的cacerts存储。
在我的情况下,解决scheme是复制JDK使用的cacerts文件(已添加新的CA),使用JRE使用的文件,并解决了问题。
只有解决scheme为我工作是
我想为smtp.gmail.com导入证书
- input命令查看此证书
D:\ openssl \ bin \ openssl.exe s_client -connect smtp.gmail.com:465
复制复制并将“—– BEGIN CERTIFICATE —–”和“—– END CERTIFICATE —–”之间的行保存到一个文件中,gmail.cer keytool -import – alias smtp.gmail.com -keystore“%JAVA_HOME%/ jre / lib / security / cacerts”-file C:\ Users \ Admin \ Desktop \ gmail.cer
-
input密码chageit
-
点击是导入证书
5.重新启动java
现在运行命令,你很好走
在尝试通过更新站点在Eclipse中安装Cucumber-Eclipse插件时遇到了这个问题。 我收到了相同的SunCertPathBuilderException错误:
Unable to read repository at http://cucumber.io/cucumber-eclipse/update-site/content.xml. Unable to read repository at http://cucumber.io/cucumber-eclipse/update-site/content.xml. sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
虽然其他一些答案对于这个问题的情况是适当的和有帮助的,但是对于我的问题来说,这些答案是无益的和误导的。
在我的情况下,问题是为他们的更新网站提供的URL是:
然而,当通过浏览器导航到它时,它redirect到(注意添加“ .github ”):
因此,解决scheme是在eclipse中添加更新站点时,简单地使用更新站点URL的redirect版本。
1.检查证书
尝试在浏览器中加载目标URL,并查看该站点的证书(通常可以通过带有locking标记的图标访问,位于浏览器地址栏的左侧或右侧)是否由于其他原因而过期或不可信。
2.安装最新版本的JRE和JDK
新版本通常附带更新后的可信任证书。
另外如果可能的话,卸载旧版本。 这将使错误configuration错误明确。
3.检查你的configuration:
- 检查你的JAVA_HOME环境variables指向的地方。
- 检查您使用哪个java版本运行程序。 在IntelliJ检查:
- 文件 – >项目结构… – >项目设置 – >项目 – >项目SDK:
- 文件 – >项目结构… – >平台设置 – > SDK
4.从新的Java版本复制整个密钥库
如果您是在JDK之下开发的,而不是最新版本 – 尝试用@ jeremy-goodellbuild议replace最新安装的JRE(首先创build一个备份副本)中的新的%JAVA_HOME%/jre/lib/security/cacerts
文件在他的回答
5.将证书添加到密钥库
如果以上没有解决您的问题,请使用keytool
将证书保存到Java的密钥库中:
keytool -trustcacerts -keystore "%JAVA_HOME%jre\lib\security\cacerts" -storepass changeit -importcert -alias <alias_name> -file <path_to_crt_file>
具有证书的文件可以从浏览器中获得,如@MagGGG在他的回答中所示 。
注1:您可能需要为每个证书链中的每一个证书重复这一点。 从根开始。
注2: <alias_name>
应该在商店中的密钥中唯一,否则keytool
将显示错误。
要获得商店中所有证书的列表,您可以运行:
keytool -list -trustcacerts -keystore "%JAVA_HOME%jre\lib\security\cacerts" -storepass changeit
如果出现问题,这将帮助您从商店中删除证书:
keytool -delete -alias <alias_name> -keystore "%JAVA_HOME%jre\lib\security\cacerts" -storepass changeit
通常情况下,这种exception发生在可信证书PATH不匹配时。 检查安全通信需要此服务器证书的configuration或path。
我有相同的问题在Ubuntu 15.10。 请尝试在本地下载插件,例如https://github.com/lmenezes/elasticsearch-kopf/archive/master.zip,然后使用以下命令进行安装:;
sudo /usr/share/elasticsearch/bin/plugin install file:/home/dev/Downloads/elasticsearch-kopf-master.zip
path可能根据您的环境而有所不同。
问候。
对我来说,证书错误popup,因为我有在后台运行的提琴手,并与证书混乱。 它作为一个代理如此接近,并重新启动日食。
添加cacerts
不适合我。 使用标志-Djavax.net.debug=all
启用日志后,然后来了解java从jssecacerts
读取。
导入jssecacerts
终于工作。
目标:
- 使用https连接
- validationSSL链
- 不要处理cacerts
- 在运行时添加证书
- 不要失去cacerts的证书
怎么做:
- 定义自己的密钥库
- 将证书放入密钥库
- 使用我们的自定义类重新定义SSL默认上下文
- ???
- 利润
我的密钥库包装文件:
public class CertificateManager { private final static Logger logger = Logger.getLogger(CertificateManager.class); private String keyStoreLocation; private String keyStorePassword; private X509TrustManager myTrustManager; private static KeyStore myTrustStore; public CertificateManager(String keyStoreLocation, String keyStorePassword) throws Exception { this.keyStoreLocation = keyStoreLocation; this.keyStorePassword = keyStorePassword; myTrustStore = createKeyStore(keyStoreLocation, keyStorePassword); } public void addCustomCertificate(String certFileName, String certificateAlias) throws Exception { TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init((KeyStore) null); Certificate certificate = myTrustStore.getCertificate(certificateAlias); if (certificate == null) { logger.info("Certificate not exists"); addCertificate(certFileName, certificateAlias); } else { logger.info("Certificate exists"); } tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(myTrustStore); for (TrustManager tm : tmf.getTrustManagers()) { if (tm instanceof X509TrustManager) { setMytrustManager((X509TrustManager) tm); logger.info("Trust manager found"); break; } } } private InputStream fullStream(String fname) throws IOException { ClassLoader classLoader = getClass().getClassLoader(); InputStream resource = classLoader.getResourceAsStream(fname); try { if (resource != null) { DataInputStream dis = new DataInputStream(resource); byte[] bytes = new byte[dis.available()]; dis.readFully(bytes); return new ByteArrayInputStream(bytes); } else { logger.info("resource not found"); } } catch (Exception e) { logger.error("exception in certificate fetching as resource", e); } return null; } public static KeyStore createKeyStore(String keystore, String pass) throws Exception { try { InputStream in = CertificateManager.class.getClass().getResourceAsStream(keystore); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(in, pass.toCharArray()); logger.info("Keystore was created from resource file"); return keyStore; } catch (Exception e) { logger.info("Fail to create keystore from resource file"); } File file = new File(keystore); KeyStore keyStore = KeyStore.getInstance("JKS"); if (file.exists()) { keyStore.load(new FileInputStream(file), pass.toCharArray()); logger.info("Default keystore loaded"); } else { keyStore.load(null, null); keyStore.store(new FileOutputStream(file), pass.toCharArray()); logger.info("New keystore created"); } return keyStore; } private void addCertificate(String certFileName, String certificateAlias) throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException { CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream certStream = fullStream(certFileName); Certificate certs = cf.generateCertificate(certStream); myTrustStore.setCertificateEntry(certificateAlias, certs); FileOutputStream out = new FileOutputStream(getKeyStoreLocation()); myTrustStore.store(out, getKeyStorePassword().toCharArray()); out.close(); logger.info("Certificate pushed"); } public String getKeyStoreLocation() { return keyStoreLocation; } public String getKeyStorePassword() { return keyStorePassword; } public X509TrustManager getMytrustManager() { return myTrustManager; } public void setMytrustManager(X509TrustManager myTrustManager) { this.myTrustManager = myTrustManager; } }
这个类将在必要时创build密钥库,并且能够pipe理其内部的证书。 现在类为SSL上下文:
public class CustomTrustManager implements X509TrustManager { private final static Logger logger = Logger.getLogger(CertificateManager.class); private static SSLSocketFactory socketFactory; private static CustomTrustManager instance = new CustomTrustManager(); private static List<CertificateManager> register = new ArrayList<>(); public static CustomTrustManager getInstance() { return instance; } private X509TrustManager defaultTm; public void register(CertificateManager certificateManager) { for(CertificateManager manager : register) { if(manager == certificateManager) { logger.info("Certificate manager already registered"); return; } } register.add(certificateManager); logger.info("New Certificate manager registered"); } private CustomTrustManager() { try { String algorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(algorithm); tmf.init((KeyStore) null); boolean found = false; for (TrustManager tm : tmf.getTrustManagers()) { if (tm instanceof X509TrustManager) { defaultTm = (X509TrustManager) tm; found = true; break; } } if(found) { logger.info("Default trust manager found"); } else { logger.warn("Default trust manager was not found"); } SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, new TrustManager[]{this}, null); SSLContext.setDefault(sslContext); socketFactory = sslContext.getSocketFactory(); HttpsURLConnection.setDefaultSSLSocketFactory(socketFactory); logger.info("Custom trust manager was set"); } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { logger.warn("Custom trust manager can't be set"); e.printStackTrace(); } } @Override public X509Certificate[] getAcceptedIssuers() { List<X509Certificate> out = new ArrayList<>(); if (defaultTm != null) { out.addAll(Arrays.asList(defaultTm.getAcceptedIssuers())); } int defaultCount = out.size(); logger.info("Default trust manager contain " + defaultCount + " certficates"); for(CertificateManager manager : register) { X509TrustManager customTrustManager = manager.getMytrustManager(); X509Certificate[] issuers = customTrustManager.getAcceptedIssuers(); out.addAll(Arrays.asList(issuers)); } logger.info("Custom trust managers contain " + (out.size() - defaultCount) + " certficates"); X509Certificate[] arrayOut = new X509Certificate[out.size()]; return out.toArray(arrayOut); } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { for(CertificateManager certificateManager : register) { X509TrustManager customTrustManager = certificateManager.getMytrustManager(); try { customTrustManager.checkServerTrusted(chain, authType); logger.info("Certificate chain (server) was aproved by custom trust manager"); return; } catch (Exception e) { } } if (defaultTm != null) { defaultTm.checkServerTrusted(chain, authType); logger.info("Certificate chain (server) was aproved by default trust manager"); } else { logger.info("Certificate chain (server) was rejected"); throw new CertificateException("Can't check server trusted certificate."); } } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { try { if (defaultTm != null) { defaultTm.checkClientTrusted(chain, authType); logger.info("Certificate chain (client) was aproved by default trust manager"); } else { throw new NullPointerException(); } } catch (Exception e) { for(CertificateManager certificateManager : register) { X509TrustManager customTrustManager = certificateManager.getMytrustManager(); try { customTrustManager.checkClientTrusted(chain, authType); logger.info("Certificate chain (client) was aproved by custom trust manager"); return; } catch (Exception e1) { } } logger.info("Certificate chain (client) was rejected"); throw new CertificateException("Can't check client trusted certificate."); } } public SSLSocketFactory getSocketFactory() { return socketFactory; } }
这个类作为singleton,因为只允许一个defaultSSL上下文。 所以现在用法:
CertificateManager certificateManager = new CertificateManager("C:\\myapplication\\mykeystore.jks", "changeit"); String certificatePath = "C:\\myapplication\\public_key_for_your_ssl_service.crt"; try { certificateManager.addCustomCertificate(certificatePath, "alias_for_public_key_for_your_ssl_service"); } catch (Exception e) { log.error("Can't add custom certificate"); e.printStackTrace(); } CustomTrustManager.getInstance().register(certificateManager);
可能的话,它不会使用这个设置,因为我将证书文件保存在资源文件夹中,所以我的path不是绝对的。 但通常情况下,它是完美的。
我面临着同样的问题,并使用以下简单的步骤解决它:
1)从谷歌下载InstallCert.java
2)使用javac InstallCert.java编译它
3)使用java InstallCert.java运行InstallCert.java,使用主机名和https端口,请求input时按“1”。 它会将“localhost”添加为可信的密钥库,并生成一个名为“jssecacerts”的文件,如下所示:
java InstallCert localhost:443
4)将jssecacerts复制到$ JAVA_HOME / jre / lib / security文件夹中
要解决这个问题的主要来源是:
https://ankurjain26.blogspot.in/2017/11/javaxnetsslsslhandshakeexception.html
问候,
ANKUR