Java:sun.security.provider.certpath.SunCertPathBuilderException:无法找到请求目标的有效证书路径
我有一个类将从 https 服务器下载文件。当我运行它时,它返回很多错误。看来我的证书有问题。是否可以忽略客户端-服务器身份验证?如果是这样,怎么办?
package com.da;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.Future;
import org.apache.http.HttpResponse;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.impl.nio.client.DefaultHttpAsyncClient;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.client.methods.AsyncCharConsumer;
import org.apache.http.nio.client.methods.HttpAsyncGet;
import org.apache.http.nio.client.methods.HttpAsyncPost;
public class RSDDownloadFile {
static FileOutputStream fos;
public void DownloadFile(String URI, String Request) throws Exception
{
java.net.URI uri = URIUtils.createURI("https", "176.66.3.69:6443", -1, "download.aspx",
"Lang=EN&AuthToken=package", null);
System.out.println("URI Query: " + uri.toString());
HttpAsyncClient httpclient = new DefaultHttpAsyncClient();
httpclient.start();
try {
Future<Boolean> future = httpclient.execute(
new HttpAsyncGet(uri),
new ResponseCallback(), null);
Boolean result = future.get();
if (result != null && result.booleanValue()) {
System.out.println("\nRequest successfully executed");
} else {
System.out.println("Request failed");
}
}
catch(Exception e){
System.out.println("[DownloadFile] Exception: " + e.getMessage());
}
finally {
System.out.println("Shutting down");
httpclient.shutdown();
}
System.out.println("Done");
}
static class ResponseCallback extends AsyncCharConsumer<Boolean> {
@Override
protected void onResponseReceived(final HttpResponse response) {
System.out.println("Response: " + response.getStatusLine());
System.out.println("Header: " + response.toString());
try {
//if(response.getStatusLine().getStatusCode()==200)
fos = new FileOutputStream( "Response.html" );
}catch(Exception e){
System.out.println("[onResponseReceived] Exception: " + e.getMessage());
}
}
@Override
protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
try
{
while (buf.hasRemaining())
{
//System.out.print(buf.get());
fos.write(buf.get());
}
}catch(Exception e)
{
System.out.println("[onCharReceived] Exception: " + e.getMessage());
}
}
@Override
protected void onCleanup() {
try
{
if(fos!=null)
fos.close();
}catch(Exception e){
System.out.println("[onCleanup] Exception: " + e.getMessage());
}
System.out.println("onCleanup()");
}
@Override
protected Boolean buildResult() {
return Boolean.TRUE;
}
}
}
错误:
URI Query: https://176.66.3.69:6443/download.aspx?Lang=EN&AuthToken=package
Aug 2, 2011 3:47:57 PM org.apache.http.impl.nio.client.NHttpClientProtocolHandler exception
SEVERE: I/O error: General SSLEngine problem
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source)
at javax.net.ssl.SSLEngine.wrap(Unknown Source)
at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:154)
at org.apache.http.impl.nio.reactor.SSLIOSession.isAppInputReady(SSLIOSession.java:276)
at org.apache.http.impl.nio.client.InternalClientEventDispatch.inputReady(InternalClientEventDispatch.java:79)
at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:161)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:335)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source)
at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:180)
... 9 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 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(Unknown Source)
... 16 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)
... 21 more
onCleanup()
[DownloadFile] Exception: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
Shutting down
Done
I have a class that will download a file from a https server. When I run it, it returns a lot of errors. It seems that I have a problem with my certificate. Is it possible to ignore the client-server authentication? If so, how?
package com.da;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.CharBuffer;
import java.util.concurrent.Future;
import org.apache.http.HttpResponse;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.impl.nio.client.DefaultHttpAsyncClient;
import org.apache.http.nio.IOControl;
import org.apache.http.nio.client.HttpAsyncClient;
import org.apache.http.nio.client.methods.AsyncCharConsumer;
import org.apache.http.nio.client.methods.HttpAsyncGet;
import org.apache.http.nio.client.methods.HttpAsyncPost;
public class RSDDownloadFile {
static FileOutputStream fos;
public void DownloadFile(String URI, String Request) throws Exception
{
java.net.URI uri = URIUtils.createURI("https", "176.66.3.69:6443", -1, "download.aspx",
"Lang=EN&AuthToken=package", null);
System.out.println("URI Query: " + uri.toString());
HttpAsyncClient httpclient = new DefaultHttpAsyncClient();
httpclient.start();
try {
Future<Boolean> future = httpclient.execute(
new HttpAsyncGet(uri),
new ResponseCallback(), null);
Boolean result = future.get();
if (result != null && result.booleanValue()) {
System.out.println("\nRequest successfully executed");
} else {
System.out.println("Request failed");
}
}
catch(Exception e){
System.out.println("[DownloadFile] Exception: " + e.getMessage());
}
finally {
System.out.println("Shutting down");
httpclient.shutdown();
}
System.out.println("Done");
}
static class ResponseCallback extends AsyncCharConsumer<Boolean> {
@Override
protected void onResponseReceived(final HttpResponse response) {
System.out.println("Response: " + response.getStatusLine());
System.out.println("Header: " + response.toString());
try {
//if(response.getStatusLine().getStatusCode()==200)
fos = new FileOutputStream( "Response.html" );
}catch(Exception e){
System.out.println("[onResponseReceived] Exception: " + e.getMessage());
}
}
@Override
protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {
try
{
while (buf.hasRemaining())
{
//System.out.print(buf.get());
fos.write(buf.get());
}
}catch(Exception e)
{
System.out.println("[onCharReceived] Exception: " + e.getMessage());
}
}
@Override
protected void onCleanup() {
try
{
if(fos!=null)
fos.close();
}catch(Exception e){
System.out.println("[onCleanup] Exception: " + e.getMessage());
}
System.out.println("onCleanup()");
}
@Override
protected Boolean buildResult() {
return Boolean.TRUE;
}
}
}
Errors:
URI Query: https://176.66.3.69:6443/download.aspx?Lang=EN&AuthToken=package
Aug 2, 2011 3:47:57 PM org.apache.http.impl.nio.client.NHttpClientProtocolHandler exception
SEVERE: I/O error: General SSLEngine problem
javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source)
at javax.net.ssl.SSLEngine.wrap(Unknown Source)
at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:154)
at org.apache.http.impl.nio.reactor.SSLIOSession.isAppInputReady(SSLIOSession.java:276)
at org.apache.http.impl.nio.client.InternalClientEventDispatch.inputReady(InternalClientEventDispatch.java:79)
at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:161)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:335)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275)
at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)
at java.lang.Thread.run(Unknown Source)
Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source)
at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:180)
... 9 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 com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(Unknown Source)
... 16 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)
... 21 more
onCleanup()
[DownloadFile] Exception: javax.net.ssl.SSLHandshakeException: General SSLEngine problem
Shutting down
Done
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(29)
这解决了我的问题,
我们需要将证书导入本地java。如果没有,我们可能会得到以下异常。
SSLPOKE 是一个工具,您可以在其中测试来自本地计算机的 https 连接。
测试连接的命令:
这将首先提示“输入密钥库密码:”
changeit
是默认密码。最后提示“信任此证书?[否]:”,提供“是”将证书添加到密钥库。验证:
This solved my issue,
We need to import the cert onto the local java. If not we could get the below exception.
SSLPOKE is a tool where you can test the https connectivity from your local machine.
Command to test the connectivity:
this would first prompt to "Enter keystore password:"
changeit
is the default password. and finally a prompt "Trust this certificate? [no]:", provide "yes" to add the cert to keystore.Verfication:
仅适用于 Windows,请按照以下步骤操作:
For Windows only, follow these steps:
我的 Apache 2.4 实例(使用 Comodo 通配符证书)上出现此错误的原因是 SHA-1 签名根证书的路径不完整。颁发的证书中有多个链,并且导致 SHA-1 根证书的链缺少 中间证书。现代浏览器知道如何处理这个问题,但 Java 7 默认情况下不处理它(尽管有一些复杂的方法可以在代码中完成此操作)。结果是错误消息看起来与自签名证书的情况相同:
在这种情况下,由于缺少中间证书,会生成“无法找到请求目标的有效证书路径”消息。您可以使用 SSL Labs 对服务器进行测试来检查缺少哪个证书。找到适当的证书后,下载它并将其添加到证书包中(如果服务器在您的控制之下)。或者,您可以在本地导入缺少的证书。在服务器上解决此问题是解决该问题的更通用的方法。
The source of this error on my Apache 2.4 instance (using a Comodo wildcard certificate) was an incomplete path to the SHA-1 signed root certificate. There were multiple chains in the issued certificate, and the chain leading to a SHA-1 root certificate was missing an intermediate certificate. Modern browsers know how to handle this, but Java 7 doesn't handle it by default (although there are some convoluted ways to accomplish this in code). The result is error messages that look identical to the case of self-signed certificates:
In this case, the "unable to find valid certification path to requested target" message is being produced due to the missing intermediate certificate. You can check which certificate is missing using SSL Labs test against the server. Once you find the appropriate certificate, download it and (if the server is under your control) add it to the certificate bundle. Alternatively, you can import the missing certificate locally. Accommodating this issue on the server is a more general solution to the problem.
对于那些喜欢 Debian 和预打包 Java 的人:
不要忘记检查
/etc/default/cacerts
:要删除证书:
For those who like Debian and prepackaged Java:
Don't forget to check
/etc/default/cacerts
for:To remove cert:
我只能使用代码让它工作,即不需要使用 keytool:
I was able to get it working with code only, i.e. no need to use keytool:
有很多方法可以解决这个问题...
一种方法是将 TrustStore 证书设置在密钥库文件中并将其放在应用程序的路径中,然后在 main 方法中设置这些系统属性:
另一种方法是将密钥库放置为项目 jar 文件中的资源文件并加载它:
在 Windows 中,您也可以尝试此解决方案: https://stackoverflow.com/a/59056537/980442
我从证书颁发机构 CA
.crt 创建了密钥库文件
文件以这种方式:仅供参考:https://docs.oracle.com/javadb/10.8.3.0/adminguide/cadminsslclient .html
There is a lot of way to solve this...
One way is set the TrustStore certificates in a keystore file and put it in the path of the application, and set these system properties in the main method:
Other way is place the keystore as resource file inside the project jar file and load it:
In windows you can try this solution too: https://stackoverflow.com/a/59056537/980442
I created the keystore file from a Certificate authority CA
.crt
file in this way:FYI: https://docs.oracle.com/javadb/10.8.3.0/adminguide/cadminsslclient.html
遇到了像这样的图片的问题。
尝试了一些解决方案。
但发现即使是同一个项目,在别人的工作场所也完全没问题。无需额外设置。所以我们猜测这是一个环境问题。我们尝试更改 JDK 版本、IDE 但没有成功。调查花了大约4个小时,直到我们尝试了评分最高的答案。我没有找到该答案中提到的错误,但我通过浏览器发现有关 HTTP URL(锁定)的内容是 Charles 的认证。然后我意识到我的查尔斯一直在线。只要我把它关掉,它就一切正常。
所以我留下了我的经验,可能对你的案子有帮助。
Had the issue like this image.
Tried a few solutions.
But found that even if it's same project, when it's on other one's working place, it's totally fine. No extra settings needed. So we guessed it's an enviroment issue. We tried changing JDK version, IDE but didn't work. it took about 4 hours for investigation, until we tried the top-rated answer. I didn't find the error mentioned in that answer but I found via my browser about HTTP URL (lock) that there was a certification of Charles. Then I realized my charles was on all the time. As long as I turned that off, it's working all fine.
So I left my experience that could be helpful for your case.
如果您在 2022 年来到这里并且使用的是 Mac,请按照此操作
1。下载证书。
2.通过执行命令找到您的JDK路径。
3.现在将证书导入到jdk的cert-store中。
And if you are here in 2022 and are on mac follow this
1. Download the certificate.
2. Find your JDK path by executing the command.
3. Now import the cert into the cert-store of jdk.
更新:重启有帮助是巧合(我希望如此,万岁!)。问题的真正原因是:当 Gradle 被指示使用特定密钥库时,该密钥库还必须包含所有官方根证书。否则它无法从常规存储库访问库。我必须做的是:
导入自签名证书:
添加官方根证书:
也许 Gradle 守护进程也妨碍了。如果事情开始看起来黯淡,可能值得杀死所有使用
./gradlew --status
找到的正在运行的守护进程。原始帖子:
没有人会相信这一点,我知道。不过,如果其他方法都失败了,请尝试一下:
重新启动我的 Mac 后,问题就消失了。咕噜。
背景:
./gradlew jar 一直给我“无法找到请求目标的有效证书路径”
我被困在自签名证书中,从浏览器保存,导入到 privateKeystore.jks 中。然后指示 Gradle 使用 privateKeystore.jks:
如前所述,这仅在重新启动后才有效。
UPDATE: That a reboot helped was coincidental (I hoped so, hooray!). The real cause of the problem was this: When Gradle is directed to use a specific keystore, that keystore must also contain all the official root certificates. Otherwise it cannot access libraries from regular repositories. What I had to do was this:
Import the self-signed certificate:
Add the official root certificates:
Maybe the Gradle daemon also got in the way. Might be worth killing all running daemons found with
./gradlew --status
if things start looking bleak.ORIGINAL POSTING:
Nobody will believe this, I know. Still, if all else fails, give it a try:
After a reboot of my Mac the problem was gone. Grrr.
Background:
./gradlew jar kept giving me "unable to find valid certification path to requested target"
I am stuck with a self-signed certificate, saved from browser, imported in privateKeystore.jks. Then instructed Gradle to work with privateKeystore.jks:
As mentioned, this only worked after a reboot.
我遇到了与证书错误相同的问题,这是因为 SNI:我使用的 http 客户端没有实现 SNI。所以版本更新完成了这项工作
I had the same problem with the certificates error and it was because of SNI: the http client that I used didn't have SNI implemented. So a version update did the job
这适用于您只需要安装 JDK 的任何操作系统:
从远程服务器下载证书:
keytool -printcert -rfc -sslserver <您的远程服务器主机名> > /tmp/remorte-cert.crt
将证书导入到您的 JDK 密钥库:
keytool -importcert -file /tmp/remorte-cert.crt -alias <远程服务器的别名> -storepass changeit -keystore " ${JAVA_HOME}/lib/security/cacerts" -noprompt
This works on any OS you just need JDK installed :
Download the certificate from the remote server :
keytool -printcert -rfc -sslserver <your remote server hostname> > /tmp/remorte-cert.crt
Import the certificate to your JDK keystore :
keytool -importcert -file /tmp/remorte-cert.crt -alias <an alias for your remote server> -storepass changeit -keystore "${JAVA_HOME}/lib/security/cacerts" -noprompt
这也可能是由于将使用 SHA2 签名的 GoDaddy 证书与 Java 7 结合使用而导致的。
Chrome 和所有其他浏览器开始弃用使用 SHA1 签名的 SSL 证书,因为它不太安全。
有关该问题的更多信息可以找到此处,以及如何在您的服务器上解决该问题(如果您现在需要的话)。
This can also be caused by using GoDaddy certs with Java 7 that are signed using SHA2.
Chrome and all other browsers are starting to deprecate SSL certs that are signed using SHA1, as it's not as secure.
More info on the issue can be found here, as well as how to resolve it on your server if you need to now.
AVG 版本 18.1.3044(使用 Windows 10)会干扰我的本地 Spring 应用程序。
解决方案:进入名为“Web 和电子邮件”的 AVG 部分并禁用“电子邮件保护”。
如果站点不安全,AVG 会阻止证书。
AVG version 18.1.3044 (with Windows 10) interfer with my local Spring application.
Solution: enter in AVG section called "Web and email" and disable the "email protection".
AVG block the certificate if the site isn't secure.
您有两个选择,将自签名证书导入到软件将运行的每个 jvm 的 java 密钥库中,或者尝试使用非验证 ssl 工厂:
You have two options, import the self-signed cert into java's keystore for each jvm the software will run on or try the non-validating ssl factory:
确保 https://176.66.3.69:6443/ 具有有效的证书。
您可以先通过浏览器查看如果它在浏览器中工作,它也会在 java 中工作。
这对我有用
Make sure that the https://176.66.3.69:6443/ have a valid certificate.
you can check it via browser firstly if it works in browser it will work in java.
that is working for me
由于最初的问题是 - 如何忽略证书错误,这里是使用 SpringBoot 和 RestTemplate 的解决方案
As original question was - how to ignore the cert error, here is solution for those using SpringBoot and RestTemplate
如果在 maven 或使用 TestNG 的 maven 中出现此错误:
-Djavax.net.ssl.trustStore=C:\Users\me.keystore -Djavax.net.ssl.trustStorePassword=X
其中 X 是您在 keytool 步骤中使用的密码。
注意:C:\Users\me.keystore 也应该设置为与您的计算机相匹配。
例如 :
If getting this error in maven, or maven with TestNG :
-Djavax.net.ssl.trustStore=C:\Users\me.keystore -Djavax.net.ssl.trustStorePassword=X
Where X is the password you used at the keytool step.
note : C:\Users\me.keystore should also be set to match your machine.
For instance :
就我而言,我正在运行带有 Java 1.6 的 MacOs High Sierra。 cacert 文件所在的位置与上面 Gabe Martin-Dempesy 的答案中引用的位置不同。 cacert 文件也已链接到另一个位置 (/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts)。
我使用 FireFox 将证书从相关网站导出到名为“exportedCertFile.crt”的本地文件。从那里,我使用 keytool 将证书移动到 cacert 文件中。这解决了问题。
In my case I'm running MacOs High Sierra with Java 1.6. The cacert file is in a different location than referenced above in Gabe Martin-Dempesy's answer. The cacert file was also already linked to another location (/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/lib/security/cacerts).
Using FireFox, I exported the certificate from the web site in question to a local file called "exportedCertFile.crt". From there, I used keytool to move the certificate into the cacert file. This fixed the problem.
首先下载 ssl 证书,然后您可以转到 java bin 路径,在控制台中执行以下命令。
first Download the ssl certificate then you can go to your java bin path execute the below command in the console.
就我而言,我的密钥库和信任库都具有相同的证书,因此删除信任库会有所帮助。有时,如果您有多个证书副本,证书链可能会成为问题。
In my case I had both keystore and truststore having the same certificate so removing truststore helped. Sometimes the chain of certificates can be an issue if you've multiple copies of certificates.
这就是我在 macOS 上的工作方式。将服务器名称和服务器端口替换为您自己的。
在终端上运行这两个命令。
从远程服务器下载证书
将证书导入 Java 密钥库
重新启动您的应用程序,证书错误就会消失!
This is what worked for me on macOS. Replace server-name and server-port with your own.
Run these two commands on your terminal.
Download certificate from the remote server
Import cert to Java keystore
Restart your application and the certs errors should go away!
当您的服务器具有自签名证书时,就会出现此问题。要解决此问题,您可以将此证书添加到 JVM 的受信任证书列表中。
在本文中作者介绍了如何从浏览器获取证书并添加将其复制到 JVM 的 cacerts 文件中。您可以编辑 JAVA_HOME/jre/lib/security/cacerts 文件或使用 -Djavax.net.ssl.trustStore 参数运行应用程序。验证您也使用哪个 JDK/JRE,因为这通常会造成混乱。
另请参阅:SSL 是怎样的证书服务器名称已解析/我可以使用 keytool 添加备用名称吗? 如果遇到
java.security.cert.CertificateException: No namematching localhostfound
异常。The problem appears when your server has self signed certificate. To workaround it you can add this certificate to the list of trusted certificates of your JVM.
In this article author describes how to fetch the certificate from your browser and add it to cacerts file of your JVM. You can either edit
JAVA_HOME/jre/lib/security/cacerts
file or run you application with-Djavax.net.ssl.trustStore
parameter. Verify which JDK/JRE you are using too as this is often a source of confusion.See also: How are SSL certificate server names resolved/Can I add alternative names using keytool? If you run into
java.security.cert.CertificateException: No name matching localhost found
exception.以下是在 macOS 上对我可靠有效的方法。确保将 example.com 和 443 替换为您尝试连接的实际主机名和端口,并提供自定义别名。第一个命令从远程服务器下载提供的证书并将其以 x509 格式保存在本地。第二个命令将保存的证书加载到 Java 的 SSL 信任存储中。
在 Windows 下通过 Git Bash 或 WSL 第一个命令看起来有点不同:
Here's what reliably works for me on macOS. Make sure to replace example.com and 443 with the actual hostname and port you're trying to connect to, and give a custom alias. The first command downloads the provided certificate from the remote server and saves it locally in x509 format. The second command loads the saved certificate into Java's SSL trust store.
Under Windows via Git Bash or WSL the first command looks a bit different :
JRE_HOME/bin
或JDK/JRE/bin
JRE_HOME/bin
orJDK/JRE/bin
keytool -keystore ..\lib\security\cacerts -import -alias your.ssl.server.name -file .\relative-path-to-cert-file\your.ssl.server.name.crt
我对来自 symantec 的有效签名通配符证书也有同样的问题。
首先尝试使用 -Djavax.net.debug=SSL 运行 Java 应用程序,看看到底发生了什么。
我最终导入了中间证书,这导致证书链中断。
我从 symantec 下载了丢失的中间证书(您可以在 ssl 握手日志中看到丢失证书的下载链接:http在我的例子中为://svrintl-g3-aia.verisign.com/SVRIntlG3.cer)。
我在 java 密钥库中导入了证书。导入中间证书后,我的通配符 ssl 证书终于开始工作:
I had the same issue with a valid signed wildcard certificate from symantec.
First try running your java application with -Djavax.net.debug=SSL to see what is really going on.
I ended up importing the intermediate certificate which was causing the cert chain to break.
I downloaded the missing intermediate cert from symantec (you can see the download link to the missing cert in the ssl handshake log: http://svrintl-g3-aia.verisign.com/SVRIntlG3.cer in my case).
And I imported the cert in the java keystore. After importing the intermediate certificate my wildcard ssl cert finally started working:
@Gabe Martin-Dempesy 的回答对我有帮助。我写了一个与之相关的小脚本。使用方法非常简单。
从主机安装证书:
删除已安装的证书。
java-cert-importer.sh
@Gabe Martin-Dempesy's answer is helped to me. And I wrote a small script related to it. The usage is very simple.
Install a certificate from host:
Remove the certificate that installed already.
java-cert-importer.sh
引用自 不再有“无法”找到请求目标的有效证书路径'
请尝试此处提供的代码。这可能有帮助。
Quoting from No more 'unable to find valid certification path to requested target'
Try the code provided there. It might help.
我遵循的简单步骤。
问题:我尝试连接到端点(https://%s.blob.core.windows .net)使用一个简单的java类(main方法)。
所以我在问题中遇到了上面提到的认证问题。
解决方案:
使用浏览器(chrome)获取证书。为此,请将您的端点 URL 粘贴到浏览器中并输入。现在您将看到一个锁定图标,单击该图标-->证书-->详情-->复制到文件-->下载它。
以管理员身份打开 cmd(我使用的是 Windows),然后导航到您下载 .cer 文件的目录。
3.(可选)如果您在同一台计算机中使用多个 JDK,则将 JDK 版本更改为与应用程序中使用的版本相同。
给出默认密码:changeit
信任此证书:yes
,您就完成了。
谢谢!
Simple Steps that I followed.
problem: I was trying to connect to an endpoint(https://%s.blob.core.windows.net) using a simple java class(main method).
So I was getting this certification issue as mentioned above, in the question.
Solution:
Get the certificate using a browser(chrome). To do this paste your endpoint URL in the browser and enter. Now you will see a lock icon, click on that -->certificate--> details --> copy to files--> download it.
open the cmd(i am using windows) as admin and then navigate to the directory where you have downloaded the .cer file.
3.(Optional)If you are using multiple JDK in the same machine then change your JDK version the same as you are using in your application.
Give the default password: changeit
Trust this certificate: yes
And you are done.
Thanks!