我正在为www.udemy.com(REST Java Web Services)制作有关REST web服务的教程。教程中的示例说明,为了拥有SSL,我们必须在我的eclipse“客户端”项目中拥有一个名为“trust_store”的文件夹,其中应包含一个“key store”文件(我们有一个“客户端”项目来调用服务和一个包含REST web服务的“服务”项目 - 两个项目位于同一eclipse工作区中,一个是客户端,另一个是服务)。为了简单起见,他们建议从我们使用的glassfish应用程序服务器(glassfish \ domains \ domain1 \ config \ keystore.jks)中复制“keystore.jks”并将其放入客户端项目中我创建的这个“trust_store”文件夹中。这似乎很有道理:服务器中的自签名证书将对应于客户端trust_store中的证书。现在,我遇到了原帖提到的错误。我已经谷歌了这个问题,并读到该错误是由于客户端上的“keystore.jks”文件不包含受信任/签名证书造成的,它找到的证书是自签名的。
为了让事情更清晰,让我说一下,据我所知,“keystore.jks”包含自签名证书,“cacerts.jks”文件包含CA证书(由CA签名)。 “keystore.jks”是“keystore”,而“cacerts.jks”是“trust store”。正如评论者“Bruno”所说,“keystore.jks”是本地的,“cacerts.jks”是远程客户端的。
因此,我对自己说,嘿,glassfish也有“cacerts.jks”文件,这是glassfish的trust_store文件。 cacerts.jsk应该包含CA证书。显然,我需要让我的trust_store文件夹包含至少一个CA证书的密钥库文件。因此,我尝试将“cacerts.jks”文件放入我在客户端项目中创建的“trust_store”文件夹中,并更改VM属性以指向“cacerts.jks”而不是“keystore.jks”。那就消除了错误。我想它只需要一个CA证书就可以工作。
这可能不是生产的理想选择,甚至不适用于开发,超出了使某些东西工作的范围。例如,您可以使用“keytool”命令将CA证书添加到客户端的“keystore.jks”文件中。但无论如何,希望这至少缩小了可能导致错误的可能情况范围。
此外:我的方法似乎对客户端有用(将服务器证书添加到客户端trust_store),看起来上面的评论对解决原始帖子很有用(将客户端证书添加到服务器trust_store)。干杯。
Eclipse项目设置:
- MyClientProject(我的客户端项目)
- src(源代码)
- test(测试)
- JRE系统库
- ...
- trust_store
---cacerts.jks(证书信任库)
---keystore.jks(密钥库)
来自MyClientProject.java文件的片段:
static {
System.setProperty("javax.net.ssl.trustStore","trust_store/cacerts.jks");
System.setProperty("javax.net.ssl.trustStore","trust_store/keystore.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(new javax.net.ssl.HostnameVerifier() {
public boolean verify(String hostname, javax.net.ssl.SSLSession sslSession) {
return hostname.equals("localhost");
}
});
}