解决javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX路径构建失败错误?

我试着在我的博客上以更得体的方式格式化问题和接受的答案。

这是最初的问题。

我得到这个错误:

详细消息sun.security.validator.ValidatorException: PKIX路径 构建失败:
provider.certpath. suncertpathbuilderexception:不能 找到请求的目标

的有效认证路径 < p > javax.net.ssl.SSLHandshakeException原因: validatorexception: PKIX路径构建 失败:sun.security.provider.certpath.SunCertPathBuilderException: 无法找到请求的目标的有效认证路径

我使用Tomcat 6作为web服务器。我在同一台机器上的不同端口的不同Tomcats上安装了两个HTTPS web应用程序。假设App1(端口8443)和App2(端口443)。App1连接到App2。当App1连接到App2时,我得到上述错误。我知道这是一个非常常见的错误,所以在不同的论坛和网站上找到了许多解决方案。我在两支雄猫的server.xml中有以下条目:

keystoreFile="c:/.keystore"
keystorePass="changeit"

每个站点都说明了app2给出的证书不在app1 jvm的可信存储区中的相同原因。这似乎也是真的,当我试图在IE浏览器中点击相同的URL,它工作(与升温,有一个问题与此网站的安全证书。在这里我说继续这个网站)。但是当相同的URL被Java客户端(在我的情况下)击中时,我得到上述错误。为了把它放到信任库中,我尝试了以下三个选项:

选项1

System.setProperty("javax.net.ssl.trustStore", "C:/.keystore");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

选项2

在环境变量中设置如下

CATALINA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

选项3

在环境变量中设置如下

JAVA_OPTS -- param name
-Djavax.net.ssl.trustStore=C:\.keystore -Djavax.net.ssl.trustStorePassword=changeit ---param value

结果

但是什么都不管用。

最后什么起作用了正在执行Pascal Thivent在如何处理无效的SSL证书与Apache HttpClient?中建议的Java方法,即执行程序InstallCert。

但这种方法适用于开发盒设置,但我不能在生产环境中使用它。

我想知道为什么上面提到的三种方法都不管用,我在App2服务器的server.xml中提到了相同的值,在信任库中通过设置也提到了相同的值

# EYZ0

在App1程序中。

要了解更多信息,这是我如何建立联系:

URL url = new URL(urlStr);


URLConnection conn = url.openConnection();


if (conn instanceof HttpsURLConnection) {


HttpsURLConnection conn1 = (HttpsURLConnection) url.openConnection();
  

conn1.setHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
});


reply.load(conn1.getInputStream());
1741072 次浏览

您需要将App2的证书添加到所使用的JVM的信任存储文件中,该文件位于$JAVA_HOME\lib\security\cacerts

首先,您可以通过运行以下命令检查您的证书是否已经在信任存储区中: keytool -list -keystore "$JAVA_HOME/jre/lib/security/cacerts"(你不需要提供密码)

如果您的证书丢失,您可以通过浏览器下载它,并使用以下命令将其添加到信任存储区:

keytool -import -noprompt -trustcacerts -alias <AliasName> -file   <certificate> -keystore <KeystoreFile> -storepass <Password>

例子:

keytool -import -noprompt -trustcacerts -alias myFancyAlias -file /path/to/my/cert/myCert.cer -keystore /path/to/my/jdk/jre/lib/security/cacerts/keystore.jks -storepass changeit

导入后,您可以再次运行第一个命令来检查是否添加了证书。

Sun/Oracle的信息可以找到在这里

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX路径构建失败:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效认证路径

•当我得到错误时,我尝试谷歌表达式的含义,我发现,当服务器更改其HTTPS SSL证书时,会发生此问题,而我们的旧版本的java不识别根证书颁发机构(CA)。

•如果您可以在浏览器中访问HTTPS URL,则可以更新Java以识别根CA。

•在浏览器中,转到Java无法访问的HTTPS URL。单击HTTPS证书链(ie浏览器中有锁图标),单击锁即可查看证书。

•进入证书的“详细信息”和“复制到文件”。复制它在Base64 (c)格式。它将保存在您的桌面上。

•安装证书时忽略所有警告。

•这就是我如何收集我试图访问的URL的证书信息。

现在我必须让我的java版本知道这个证书,这样它就不会拒绝识别URL了。在这方面,我必须提到,我搜索到根证书信息默认保存在JDK的\ jre \ lib \安全位置,默认访问密码是:changeit。

查看cacerts信息的操作步骤如下:

•点击开始按钮——>运行

•输入cmd。打开命令提示符(您可能需要以管理员身份打开它)。

•进入Java/jreX/bin目录

•输入以下内容

keytool -list -keystore D:\Java\jdk1.5.0_12\jre\lib\security\cacerts

它给出密钥存储库中包含的当前证书的列表。它看起来是这样的:

C:\Documents and Settings\NeelanjanaG>keytool -list -keystore D:\Java\jdk1.5.0_12\jre\lib\security\cacerts


Enter keystore password:  changeit


Keystore type: jks


Keystore provider: SUN


Your keystore contains 44 entries


verisignclass3g2ca, Mar 26, 2004, trustedCertEntry,


Certificate fingerprint (MD5): A2:33:9B:4C:74:78:73:D4:6C:E7:C1:F3:8D:CB:5C:E9


entrustclientca, Jan 9, 2003, trustedCertEntry,


Certificate fingerprint (MD5): 0C:41:2F:13:5B:A0:54:F5:96:66:2D:7E:CD:0E:03:F4


thawtepersonalbasicca, Feb 13, 1999, trustedCertEntry,


Certificate fingerprint (MD5): E6:0B:D2:C9:CA:2D:88:DB:1A:71:0E:4B:78:EB:02:41


addtrustclass1ca, May 1, 2006, trustedCertEntry,


Certificate fingerprint (MD5): 1E:42:95:02:33:92:6B:B9:5F:C0:7F:DA:D6:B2:4B:FC


verisignclass2g3ca, Mar 26, 2004, trustedCertEntry,


Certificate fingerprint (MD5): F8:BE:C4:63:22:C9:A8:46:74:8B:B8:1D:1E:4A:2B:F6

•现在我必须将之前安装的证书包含到cacerts中。

•为此,程序如下:

keytool -import -noprompt -trustcacerts -alias ALIASNAME -file FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass PASSWORD

如果你使用的是Java 7:

keytool -importcert -trustcacerts -alias ALIASNAME -file PATH_TO_FILENAME_OF_THE_INSTALLED_CERTIFICATE -keystore PATH_TO_CACERTS_FILE -storepass changeit

•然后将证书信息添加到cacert文件中。

这是我为上面提到的异常找到的解决方案!!

我写了一个小的win32 (WinXP 32位测试)愚蠢的cmd(命令行)脚本,它在程序文件中查找所有java版本,并向它们添加一个证书。 Password需要默认为“changeit”,或者在脚本中自己修改:-)

@echo off


for /F  %%d in ('dir /B %ProgramFiles%\java') do (
%ProgramFiles%\Java\%%d\bin\keytool.exe -import -noprompt -trustcacerts -file some-exported-cert-saved-as.crt -keystore %ProgramFiles%\Java\%%d\lib\security\cacerts -storepass changeit
)


pause

我的cacerts文件完全是空的。我通过从我的windows机器(使用Oracle Java 7)复制cacerts文件并将其scp到我的Linux盒子(OpenJDK)来解决这个问题。

cd %JAVA_HOME%/jre/lib/security/
scp cacerts mylinuxmachin:/tmp

然后在Linux机器上

cp /tmp/cacerts /etc/ssl/certs/java/cacerts

到目前为止,它工作得很好。

对于运行在Ubuntu服务器上的Tomcat,使用"ps -ef | grep Tomcat "命令查看正在使用的Java:

示例:

/home/mcp01$ **ps -ef |grep tomcat**
tomcat7  28477     1  0 10:59 ?        00:00:18 **/usr/local/java/jdk1.7.0_15/bin/java** -Djava.util.logging.config.file=/var/lib/tomcat7/conf/logging.properties -Djava.awt.headless=true -Xmx512m -XX:+UseConcMarkSweepGC -Djava.net.preferIPv4Stack=true -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/usr/share/tomcat7/endorsed -classpath /usr/share/tomcat7/bin/bootstrap.jar:/usr/share/tomcat7/bin/tomcat-juli.jar -Dcatalina.base=/var/lib/tomcat7 -Dcatalina.home=/usr/share/tomcat7 -Djava.io.tmpdir=/tmp/tomcat7-tomcat7-tmp org.apache.catalina.startup.Bootstrap start
1005     28567 28131  0 11:34 pts/1    00:00:00 grep --color=auto tomcat

然后,我们可以进入:cd /usr/local/java/jdk1.7.0_15 / jre / lib /安全

默认的文件位于这里。将不受信任的证书插入其中。

如何在Tomcat 7中工作

我想在Tomcat应用程序中支持自签名证书,但是下面的代码段无法工作

import java.io.DataOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;


public class HTTPSPlayground {
public static void main(String[] args) throws Exception {


URL url = new URL("https:// ... .com");
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();


httpURLConnection.setRequestMethod("POST");
httpURLConnection.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
httpURLConnection.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(httpURLConnection.getOutputStream());


String serializedMessage = "{}";
wr.writeBytes(serializedMessage);
wr.flush();
wr.close();


int responseCode = httpURLConnection.getResponseCode();
System.out.println(responseCode);
}
}

这就是解决我问题的方法:

1)下载.crt文件

echo -n | openssl s_client -connect <your domain>:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > ~/<your domain>.crt
  • <your domain>替换为您的域(例如jossef.com)

2)在Java的cacerts证书存储区中应用.crt文件

keytool -import -v -trustcacerts -alias <your domain> -file ~/<your domain>.crt -keystore <JAVA HOME>/jre/lib/security/cacerts -keypass changeit -storepass changeit
  • <your domain>替换为您的域(例如jossef.com)
  • <JAVA HOME>替换为java主目录

3)破解

尽管iv在Java的默认证书存储区中安装了我的证书,Tomcat会忽略它(似乎它没有配置为使用Java的默认证书存储区)。

要破解这个问题,在代码中添加以下代码:

String certificatesTrustStorePath = "<JAVA HOME>/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);


// ...

我也有这个问题。

我尝试了几乎所有的方法,将SSL证书添加到.keystore,但是,它不能与Java1_6_x一起工作。 对我来说,如果我们开始使用新版本的Java, Java1_8_x作为JVM,这是有帮助的

在Linux下使用Tomcat 7,这就成功了。

String certificatesTrustStorePath = "/etc/alternatives/jre/lib/security/cacerts";
System.setProperty("javax.net.ssl.trustStore", certificatesTrustStorePath);
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");

在Linux下,$JAVA_HOME并不总是设置,但通常/etc/alternatives/jre指向$JAVA_HOME/jre

对我来说,这个错误也出现在试图连接到一个NGINX反向代理背后的进程,它正在处理SSL。

原来问题是一个没有连接整个证书链的证书。 当我添加中间certs时,问题就解决了

希望这能有所帮助。

另一个原因可能是JDK的过时版本。我使用的jdk版本为1.8.0_60,只需更新到最新版本就解决了证书问题。

可以通过编程方式禁用SSL验证。在紧要关头适用于开发,但不建议用于生产,因为您可能需要使用"real"SSL验证或安装并使用您自己的可信密钥,然后仍然使用“real"SSL验证。

下面的代码为我工作:

import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;


import javax.net.ssl.X509TrustManager;


public class TrustAnyTrustManager implements X509TrustManager {


public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}


public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}


public X509Certificate[] getAcceptedIssuers() {
return null;
}
}

             HttpsURLConnection conn = null;
URL url = new URL(serviceUrl);
conn = (HttpsURLConnection) url.openConnection();
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());
// Create all-trusting host name verifier
HostnameVerifier allHostsValid = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
conn.setHostnameVerifier(allHostsValid);

或者如果你不控制下面的# eyz0,你也可以覆盖SSL验证的所有连接https://stackoverflow.com/a/19542614/32453

如果你正在使用Apache HTTPClient,你必须以不同的方式禁用它。(不幸的是):# EYZ0

当我遇到同样的问题时,我正在使用jdk1.8.0_171。我在这里尝试了前2个解决方案(使用keytool添加证书和另一个解决方案,其中有一个黑客),但他们不适合我。

我将JDK升级到1.8.0_181,它的工作效果非常好。

在我的例子中,问题是web服务器只发送证书和中间CA,而不是根CA。 添加这个JVM选项解决了这个问题:-Dcom.sun.security.enableAIAcaIssuers=true

支持权威信息访问扩展的caissuer访问方法是可用的。为了兼容性,它默认是禁用的,可以通过将系统属性com.sun.security.enableAIAcaIssuers设置为true来启用。

如果设置为true, Sun的CertPathBuilder的PKIX实现将使用证书的AIA扩展中的信息(除了指定的CertStores之外)来查找颁发的CA证书,前提是它是ldap、http或ftp类型的URI。

Source .

为了安全起见,我们不应该在实现中使用自签名证书。然而,当涉及到开发时,我们经常不得不使用获得自签名证书的试验环境。我试图在我的代码中以编程方式解决这个问题,但我失败了。但是,通过将证书添加到jre信任存储区,解决了我的问题。请参考以下步骤,

  1. 下载站点证书

    • 使用# EYZ0
    • 使用# EYZ0
    • 李< / ul > < / >
    • 将证书(例如:cert_file.cer)复制到$JAVA_HOME\Jre\Lib\Security目录

    • 在“管理员”中打开CMD,将目录更改为“$JAVA_HOME\Jre\Lib\Security”

    • 使用以下命令将证书导入信任存储区,

keytool -import -alias ca -file cert_file.cer -keystore cacerts 对于storepass changeit < / p >

如果你得到一个错误说keytool是不可识别的,请参考这个

键入是的,如下所示

信任这个证书:(是的)

  1. 现在尝试使用java以编程方式运行代码或访问URL。

更新

如果你的应用服务器是jboss,尝试添加下面的系统属性

System.setProperty("org.jboss.security.ignoreHttpsHost","true");

希望这能有所帮助!

对于MacOS X,下面是我必须在'importcert'选项中尝试双连字符的确切命令,这是有效的:

sudo keytool -–importcert -file /PathTo/YourCertFileDownloadedFromBrowserLockIcon.crt -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_191.jdk/Contents/Home/jre/lib/security/cacerts -alias "Cert" -storepass changeit

我有这个问题与Android工作室当我背后的代理。我使用的是Crashlytics,它试图在构建过程中上传映射文件。

我将丢失的代理证书添加到位于 # EYZ0 < / p >

使用以下命令:keytool -import -trustcacerts -keystore cacerts -storepass [password] -noprompt -alias [alias] -file [my_certificate_location]

为例,使用默认信任库密码 # EYZ0 < / p >

必要时,您可以完全禁用SSL,或者每个连接禁用SSL(注意,这不建议用于生产环境!),参见https://stackoverflow.com/a/19542614/32453

对我来说,这篇文章中的解决方案https://stackoverflow.com/a/9619478/4507034并不奏效。

相反,我设法通过将认证导入到我的机器信任的认证来解决这个问题。

步骤:

  1. 转到URL(例如。https://localhost:8443/yourpath),其中认证不起作用。
  2. 导出上述帖子中描述的认证。
  3. 在你的windows机器上打开:Manage computer certificates
  4. 转到Trusted Root Certification Authorities -> Certificates
  5. 在这里导入your_certification_name.cer文件。

只是一个小hack。将“hudson.model.UpdateCenter.xml”文件中的URL从https更新为http

<?xml version='1.1' encoding='UTF-8'?>
<sites>
<site>
<id>default</id>
<url>http://updates.jenkins.io/update-center.json</url>
</site>
</sites>

可部署解决方案(Alpine Linux)

为了能够在我们的应用程序环境中修复这个问题,我们准备了如下的Linux终端命令:

cd ~

将在主目录中生成证书文件。

apk add openssl

该命令在alpine Linux中安装openssl。您可以找到其他Linux发行版的适当命令。

openssl s_client -connect <host-dns-ssl-belongs> < /dev/null | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > public.crt

生成所需的证书文件。

sudo $JAVA_HOME/bin/keytool -import -alias server_name -keystore $JAVA_HOME/lib/security/cacerts -file public.crt -storepass changeit -noprompt

使用'keytool'程序将生成的文件应用到JRE。

请将您的DNS替换为<host-dns-ssl-belongs>

请注意,-noprompt将不会提示验证消息(是/否),-storepass changeit参数将禁用密码提示并提供所需的密码(默认为'changeit')。这两个属性将允许您在应用程序环境中使用这些脚本,例如构建Docker映像。

如果你通过Docker部署你的应用程序,你可以生成一次秘密文件,并把它放在你的应用程序项目文件中。您不需要一次又一次地生成它。

我想加入进来,因为我有一个QEMU环境,我必须在其中下载java文件。事实证明QEMU中的/etc/ssl/certs/java/cacerts确实有问题,因为它与主机环境中的/etc/ssl/certs/java/cacerts不匹配。主机环境位于公司代理的后面,因此java cacerts是一个定制版本。

如果您正在使用QEMU环境,请首先确保主机系统可以访问文件。例如,您可以先在主机上尝试这个脚本来查看。如果脚本在主机上运行得很好,但在QEMU上却不行,那么您也遇到了和我一样的问题。

为了解决这个问题,我必须对QEMU中的原始文件进行备份,将主机环境中的文件复制到QEMU chroot jail中,然后java才能在QEMU中正常下载文件。

更好的解决方案是将/etc挂载到QEMU环境中;但是我不确定其他文件是否会在这个过程中受到影响。所以我决定使用这个丑陋但简单的变通方法。

这里似乎是记录臭名昭著的PKIX错误消息的另一个可能原因的好地方。在花了太长时间查看密钥库和信任库内容以及各种java安装配置之后,我意识到我的问题在于……一个错字。

输入错误意味着我还使用密钥存储库作为信任存储库。由于我的公司根CA没有被定义为keystore中的独立证书,而只是证书链的一部分,并且没有在其他任何地方定义(即cacerts),我一直得到PKIX错误。

在一次失败的发布之后(这是prod配置,在其他地方是可以的),经过两天的挠头,我终于看到了错别字,现在一切都好了。

希望这能帮助到一些人。

我的观点是: 在我的例子中,cacerts不是一个文件夹,而是一个文件,而且它在两个路径上呈现 发现该错误后,将.jks文件复制到该文件上后错误消失
# locate cacerts
/usr/java/jdk1.8.0_221-amd64/jre/lib/security/cacerts
/usr/java/jre1.8.0_221-amd64/lib/security/cacerts

备份后,我复制。jks。

cp /path_of_jks_file/file.jks /usr/java/jdk1.8.0_221-amd64/jre/lib/security/cacerts
cp /path_of_jks_file/file.jks /usr/java/jre1.8.0_221-amd64/lib/security/cacerts

注意:这个基本技巧解决了Genexus项目中的这个错误,尽管文件。jks也在Tomcat的server.xml文件中。

  • 确定JVM位置。可能有6个jre是打开的 您的系统。您的Tomcat真正使用的是哪一个?在任何地方 在Tomcat中运行的代码,编写 println (System.getProperty(“java.home"))。注意这个位置。在 java.home>/lib/security/cacerts文件是 李Tomcat。< / >
  • 查找正在失效的根证书。这可以是 通过使用-Djavax.net.debug=all打开SSL调试来找到。运行您的 app和控制台ssl日志中的CA正在失败。它的url 将可用。在我的情况下,我惊讶地发现代理zscaler是一个失败的,因为它实际上是代理我的调用,并返回自己的CA证书
  • 在浏览器中粘贴url。证书将获得 李下载。< / >
  • 使用keytool Import将该证书导入cacerts。

我在AWS EC2中运行的应用服务器上进行REST调用时遇到了这个问题。以下步骤为我解决了这个问题。

  1. Curl -vs https://your_rest_path
  2. Echo | openssl s_client -connect your_domain:443
  3. Sudo apt-get install ca-certificates

Curl -vs https://your_rest_path现在可以工作了!

我在Apache Tomcat/7.0.67和Java JVM Version: 1.8.0_66-b18上也有同样的问题。随着Java升级到JRE 1.8.0_241,这个问题似乎已经解决了。

如果您使用的是JDK 11,则该文件夹中不再包含JRE。certs的位置是jdk-11.0.11/lib/security/cacerts。

我正在使用颤振,却突然收到这个错误。所以,基本上发生的是你的依赖在android/build.gradle文件中的行,如:

  classpath 'com.android.tools.build:gradle:4.1.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"

要求从网上下载成绩文件的证明。但是当有什么东西阻止gradle下载这些证书时,通常会显示这个。

我尝试导出证书并手动添加它,但它似乎对我不起作用。对我有效的方法是,在无数次绞尽脑汁之后,从你的网络首选项中禁用代理。有地方提到,禁用查尔斯代理将解决它,但在那一刻,我不知道查尔斯是什么,代理是什么。在我的情况下,我没有查尔斯代理的事情,所以我继续在Mac的网络首选项设置中寻找代理(它可以在Windows的网络设置中找到)。我在代理中启用了Socks。我禁用了它,然后再次重建gradle和TA-DAH!!它工作起来像黄油一样光滑。

有几件事要记住。如果您在没有关闭网络首选项选项卡的情况下禁用代理后立即构建项目,禁用代理将不起作用,它将显示相同的错误。此外,如果您已经构建了项目,并且在禁用代理后再次运行它,它很可能会显示相同的错误(可能是由于IDE缓存)。我的工作原理:重启Mac,在浏览器中打开几个选项卡(进行几个网络调用),从系统首选项>>Wifi和禁用代理,关闭系统首选项应用程序,并构建项目。

关注@NDeveloper的精彩答案。当然,我做了复制粘贴,改变了值,我得到

Illegal option:  ?import

我确实签出了连字符,我看到答案是使用ASCII的连字符

– 8211

如果你遇到问题,检查ASCII码,为我做的伎俩是这个代码= 45

- 45

我的代码

keytool -import -noprompt -trustcacerts -alias Certificado -file "C:\Users\JavIut\Desktop\Company\Certificados\Certificado.cer" -keystore "C:\Program Files\Java\jdk1.8.0_121\jre\lib\security\cacerts"
对于OkHttpClient,这个解决方案对我有效。

try {


String proxyHost = "proxy_host";
String proxyUsername = "proxy_username";
String proxyPassword = "proxy_password";


Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyHost, "port goes here"));


// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};


// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();


OkHttpClient client = new OkHttpClient().newBuilder()
.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
.hostnameVerifier((hostname, session) -> true)
.connectTimeout(timeout, TimeUnit.SECONDS)
.proxy(proxy)
.proxyAuthenticator((route, response) -> {
String credential = Credentials.basic(proxyUsername, proxyPassword);
return response.request().newBuilder()
.header("Proxy-Authorization", credential)
.build();
})
.build();


MediaType mediaType = MediaType.parse("application/json");
RequestBody requestBody = RequestBody.create(payload, mediaType);


Request request = new Request.Builder()
.url(url)
.header("Authorization", "authorization data goes here")
.method(requestMethod, requestBody)
.build();


Response response = client.newCall(request).execute();


resBody = response.body().string();


int responseCode = response.code();


} catch (Exception ex) {
}

查看各种证书内容和通过标准openssl过程生成的证书,我注意到openssl根证书的AutorityKeyIdentifier被设置为本身。也许有一种方法可以克服它……但我不知道……

然后我用Java11 &开发了一个小应用程序;BouncyCastle生成根证书和密钥,现在在github上:https://github.com/kendarorg/JavaCaCertGenerator

使用该工具生成的根证书不包含AuthorityKeyIdentifier,可以使用keytool直接安装在cacert存储区上。当我创建然后csr和ext文件的域名,这将验证对cacert存储包含根..再也没有握手异常了!

可能是cacert不允许递归AuthorityKeyIdentifier?我不知道,但我会欣赏一些评论:)

我在Android Studio中得到这个错误。所以我做了很多研究之后。

“Password”为“changeit”

步骤1:以管理员身份打开CMD

第二步:输入“powershell”;

步骤3:start-process powershell -verb runas

步骤4:在C:\Program Files\Android\Android中添加所有的Certificate

. Studio\jre\lib\security cacert可用的位置

第五步:打开Keytool目录Set-Location -Path "C:\Program Files\Android\Android Studio\jre\bin"

C:\Program Files\Android\Android Studio\jre\lib\security\Replace With Your Certificate name.cerkeystore除

步骤7:如果错误出现为证书已添加(访问被拒绝),然后创建一个D驱动器分区(https://www.diskpart.com/windows-10/how-to-create-d-drive-from-c-drive-in-windows-10-0725.html)或将文件移动到D驱动器,然后添加证书

如果你把文件保存在D盘,那么只执行这个

D:\Certificatename.cer"keystore除

\keytool -list -keystore cacerts . keystore cacerts . keystore - cacerts . keystore - cacerts . keystore - cacerts . keystore