我有一个Java客户端试图使用自签名证书访问服务器。

当我试图发布到服务器,我得到以下错误:

无法找到请求目标的有效认证路径

在对这个问题做了一些研究之后,我做了以下工作。

保存我的服务器域名为根。cer文件。 在我的Glassfish服务器的JRE中,我运行了这个: Keytool -import -alias example -keystore cacerts -file root.cer 为了检查证书是否成功添加到我的cacert,我这样做: Keytool -list -v -keystore cacerts 我可以看到证书是存在的。 然后我重新启动Glassfish并重新尝试“post”。

我还是得到同样的错误。

我有一种感觉,这是因为我的Glassfish实际上没有读取我修改过的cacert文件,但可能是其他一些文件。

你们中有人遇到过这样的问题吗,可以帮我找到正确的方向吗?


当前回答

检查$JAVA_HOME/lib/security/cacerts文件是否存在! 在我的情况下,它不是一个文件,而是一个到/etc/ssl/certs/java/cacerts的链接,而且这是一个到自身的链接(什么??),因此JVM无法找到该文件。

解决方案: 复制真正的cacerts文件(你可以从另一个JDK)到/etc/ssl/certs/java/目录,它将解决你的问题:)

其他回答

eclipse / Sts用户注意:

因为eclipse使用它自己的JRE,您应该将cert添加到它自己的JRE密钥存储库中。 我有这个问题,直到我添加certs到圣的JRE。

SSL日志:

`javax.net.ssl|DEBUG|1A|restartedMain|2021-12-06 23:04:00.874` IRST|TrustStoreManager.java:113|trustStore is: D:\sts-4.12.0.RELEASE\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_16.0.2.v20210721-1149\jre\lib\security\cacerts
This is the full path: "sts-4.12.0.RELEASE\plugins\org.eclipse.justj.openjdk.hotspot.jre.full.win32.x86_64_16.0.2.v20210721-1149\jre\lib\security\cacerts"

I am working on a tutorial for REST web services at www.udemy.com (REST Java Web Services). The example in the tutorial said that in order to have SSL, we must have a folder called "trust_store" in my eclipse "client" project that should contain a "key store" file (we had a "client" project to call the service, and "service" project that contained the REST web service - 2 projects in the same eclipse workspace, one the client, the other the service). To keep things simple, they said to copy "keystore.jks" from the glassfish app server (glassfish\domains\domain1\config\keystore.jks) we are using and put it into this "trust_store" folder that they had me make in the client project. That seems to make sense: the self-signed certs in the server's key_store would correspond to the certs in the client trust_store. Now, doing this, I was getting the error that the original post mentions. I have googled this and read that the error is due to the "keystore.jks" file on the client not containing a trusted/signed certificate, that the certificate it finds is self-signed.

为了让事情更清楚,让我说一下我理解的“密钥库”。“Jks”包含自签名的certs,以及“cacerts. Jks”。“jks”文件中包含CA证书(由CA签名)。“密钥存储库。Jks是“密钥存储库”,cacerts是“cacerts”。Jks”是“信任商店”。正如一位名叫“布鲁诺”的评论者所说,“密钥库。Jks是本地的,cacerts是本地的。Jks”用于远程客户端。

So, I said to myself, hey, glassfish also has the "cacerts.jks" file, which is glassfish's trust_store file. cacerts.jsk is supposed to contain CA certificates. And apparently I need my trust_store folder to contain a key store file that has at least one CA certificate. So, I tried putting the "cacerts.jks" file in the "trust_store" folder I had made, on my client project, and changing the VM properties to point to "cacerts.jks" instead of "keystore.jks". That got rid of the error. I guess all it needed was a CA cert to work.

这对于生产来说可能并不理想,甚至对于开发来说也不理想。例如,您可以使用“keytool”命令将CA证书添加到“密钥存储库”中。Jks”文件在客户端。但无论如何,希望这至少能缩小可能导致错误的情况。

另外:我的方法似乎对客户端有用(服务器证书添加到客户端trust_store),看起来上面解决原始帖子的注释对服务器有用(客户端证书添加到服务器trust_store)。欢呼。

Eclipse项目设置:

MyClientProject src 测验 JRE系统库 ... trust_store ——cacerts.jks ——keystore.jks

MyClientProject.java文件片段:

static {
  // Setup the trustStore location and password
  System.setProperty("javax.net.ssl.trustStore","trust_store/cacerts.jks");
  // comment out below line
  System.setProperty("javax.net.ssl.trustStore","trust_store/keystore.jks");
  System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
  //System.setProperty("javax.net.debug", "all");

  // for localhost testing only
  javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
        public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
          return hostname.equals("localhost");
        }

  });
}

不幸的是——这可能是很多事情——很多应用服务器和其他java“包装器”都倾向于玩弄属性和他们自己的钥匙链等。所以它可能会看一些完全不同的东西。

少了桁架-我会试试:

java -Djavax.net.debug=all -Djavax.net.ssl.trustStore=trustStore ...

看看这是否有用。除了“all”,还可以将其设置为“ssl”,密钥管理器和信任管理器-这可能对您的情况有帮助。在大多数平台上,将它设置为“帮助”会列出如下内容。

无论如何,一定要确保您完全理解密钥存储库(其中有您用来证明自己身份的私钥和证书)和信任存储库(它决定您信任谁)之间的区别,以及您自己的身份也有一个到根的信任“链”,这与您需要确定您信任“谁”的根的任何链是分开的。

all            turn on all debugging
ssl            turn on ssl debugging

The   following can be used with ssl:
    record       enable per-record tracing
    handshake    print each handshake message
    keygen       print key generation data
    session      print session activity
    defaultctx   print default SSL initialization
    sslctx       print SSLContext tracing
    sessioncache print session cache tracing
    keymanager   print key manager tracing
    trustmanager print trust manager tracing
    pluggability print pluggability tracing

    handshake debugging can be widened with:
    data         hex dump of each handshake message
    verbose      verbose handshake message printing

    record debugging can be widened with:
    plaintext    hex dump of record plaintext
    packet       print raw SSL/TLS packets

来源:#见http://download.oracle.com/javase/1.5.0/docs/guide/security/jsse/JSSERefGuide.html#Debug

(转载自我的其他回复) 使用java软件发行版中的cli实用工具keytool导入(并信任!)所需的证书

示例:

从命令行更改目录到jre\bin 检查密钥库(在jre\bin目录中找到的文件) Keytool -list -keystore ..\lib\security\cacerts . txt 密码为changeit 从需要的服务器下载并保存链中的所有证书。 添加证书(在需要删除文件..\lib\security\cacerts上的“只读”属性之前),运行: keytool -alias REPLACE_TO_ANY_UNIQ_NAME -import -keystore.使用实例\lib\security\cacerts -file "r:\root.crt"

我偶然发现了这么一个简单的小窍门。 其他解决方案需要使用InstallCert.Java和JDK

来源:http://www.java-samples.com/showtutorial.php?tutorialid=210

I had the same problem with sbt. It tried to fetch dependencies from repo1.maven.org over ssl but said it was "unable to find valid certification path to requested target url". so I followed this post and still failed to verify a connection. So I read about it and found that the root cert is not enough, as was suggested by the post,so - the thing that worked for me was importing the intermediate CA certificates into the keystore. I actually added all the certificates in the chain and it worked like a charm.