Keytool创建一个受信任的自签名证书 [英] Keytool create a trusted self signed certificate

查看:323
本文介绍了Keytool创建一个受信任的自签名证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用(java)keytool创建自签名证书,但当我尝试使用它,我得到以下异常(请参阅底部的整个异常)。

  ...< 5 more exceptions above this> 
导致:sun.security.validator.ValidatorException:未找到可信证书
at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:304)
at sun.security.validator .SimpleValidator.engineValidate(SimpleValidator.java:107)
at sun.security.validator.Validator.validate(Validator.java:203)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl .checkServerTrusted(X509TrustManagerImpl.java:172)
at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
at com.sun.net.ssl.internal .ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
...还有22个

我知道我可以绕过这个代码:

  import javax.net.ssl.HostnameVerifier; 
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

HostnameVerifier hv = new HostnameVerifier(){
public boolean verify(String urlHostName,SSLSession session){
System.out.println(Warning:URL Host:+ urlHostName +vs.+ session.getPeerHost());
return true;
}
};

HttpsURLConnection.setDefaultHostnameVerifier(hv);

(源)



但我对这个解决方案不感兴趣,因为我认为它创建一个安全漏洞。 (如果我错了,请纠正我)。



任何人都能指向正确的方向?我现在正在测试本地,所以这是很容易改变的事情。我可以访问服务器代码,客户端代码和.keystore文件。



更新



我试图为客户端和服务器使用一个.keystore文件,但希望简化我的问题我创建了server.keystore(见下文)和client.truststore(见下文)。我有理由相信,证书是正确的,但如果有人可以验证,我将不胜感激。



server.keystore

 主机名[username:/ this / is / a / path] [711]%keytool -list -keystore server.keystore -v 
输入密钥库密码:

密钥库类型:JKS
密钥库提供程序:SUN

您的密钥库包含1个条目

别名:主机名
创建日期:2010年2月4日
条目类型:PrivateKeyEntry
证书链长度:1
证书[1]:
所有者:CN =主机名,OU =主机名,O =主机名,L =主机名,ST =主机名,C =主机名
:CN =主机名,OU =主机名,O =主机名,L =主机名,ST =主机名,C =主机名
序列号:4b6b0ea7
有效期为:Thu Feb 04 13:15:03 EST 2010 until :Wed May 05 14:15:03 EDT 2010
证书指纹:
MD5:81:C0:3F:EC:AD:5B:7B:C4:DA:08:CC:D7: 1F:1D:38
SHA1:F1:78:AD:C8:D0:3A:4C:0C:9A:4F:89:C0:2A:2F:E2:E6:D5:13:
签名算法名称:SHA1withDSA
版本:3


********************** *********************
************************* ******************

client.truststore

  hostname [username:/ this / is / a / path]%keytool  - list -keystore client.truststore -v 
输入密钥库密码:

密钥库类型:JKS
密钥库提供程序:SUN

您的密钥库包含1个条目

别名:mykey
创建日期:2010年2月4日
条目类型:trustedCertEntry

所有者:CN =主机名,OU =主机名,O =主机名,L =主机名,ST =主机名,C =主机名
发行者:CN =主机名,OU =主机名,O =主机名,L =主机名,ST =主机名,C =主机名
序列号:4b6b0ea7
有效期从:2004年2月04日13:15:03 EST 2010年至2010年5月5日14:15:03 EDT 2010
证书指纹:
MD5:81:C0:3F:EC: AD:5B:7B:C4:DA:08:CC:D7:11:1F:1D:38
SHA1:F1:78:AD:C8:D0:3A:4C:0C:9A:4F:89 :C0:2A:2F:E2:E6:D5:13:96:40
签名算法名称:SHA1withDSA
版本:3


**** ***************************************
******* ************************************



更新



我认为包含整个例外是有用的:

  javax.xml.soap.SOAPException:java.io.IOException:无法在org.jboss.ws.core.soap传输消息
。 SOAPConnectionImpl.callInternal(SOAPConnectionImpl.java:115)
at org.jboss.ws.core.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:66)
at com.alcatel.tpapps.common.utils。 SOAPClient.execute(SOAPClient.java:193)
at com.alcatel.tpapps.common.utils.SOAPClient.main(SOAPClient.java:280)
引发者:java.io.IOException:无法发送消息
在org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:192)
在org.jboss.ws.core.client.SOAPRemotingConnection.invoke(SOAPRemotingConnection.java: 77)
at org.jboss.ws.core.soap.SOAPConnectionImpl.callInternal(SOAPConnectionImpl.java:106)
... 3更多
原因:org.jboss.remoting.CannotConnectException :无法连接http客户端调用者。 sun.security.validator.ValidatorException:未找到可信证书。
at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:368)
at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:148)
at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:141)
at org.jboss.remoting.Client.invoke(Client.java:1858)
at org.jboss .remoting.Client.invoke(Client.java:718)
at org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:171)
...另外5个
Caused by:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:未找到可信证书
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150 )
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1584)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker .java:174)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
at com.sun.net.ssl.internal.ssl.ClientHandshaker .serverCertificate(ClientHandshaker.java:848)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
at com.sun.net.ssl.internal .ssl.Handshaker.processLoop(Handshaker.java:495)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
at com.sun.net .ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:877)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089)
at com .sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1116)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1100)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:402)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:857)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:288)
...另外10个
引发者:sun.security.validator.ValidatorException:无信任证书发现
at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:304)
at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:107)
at sun。 security.validator.Validator.validate(Validator.java:203)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
at com.sun。 net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
。 .. 22更多


解决方案

你的服务器和客户端之间(我假设你只需要做服务器端身份验证)。这是因为你使用自签名证书。
这包括将您的服务器的证书导入客户端信任库:



在服务器端:

  keytool -keystore< keystore file> -alias< alias> -export -file< certfilename> .cert 

将.cert文件复制到客户端然后:

  keytool -keystore< truststore file> -alias< alias> -import -file< certfilename> .cert 


I am trying to use the (java) keytool to create a self signed certificate but when I attempt to use it I get the following exception (see bottom for entire exception).

...<5 more exceptions above this>
Caused by: sun.security.validator.ValidatorException: No trusted certificate found
        at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:304)
        at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:107)
        at sun.security.validator.Validator.validate(Validator.java:203)
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
        at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
        ... 22 more

I know that I can by-pass this with this code:

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSession;

HostnameVerifier hv = new HostnameVerifier() {
    public boolean verify(String urlHostName, SSLSession session) {
        System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
        return true;
    }
};

HttpsURLConnection.setDefaultHostnameVerifier(hv);

(source)

But I am not interested in this solutions because I think that it creates a security hole. (please correct me if I am wrong).

Can anyone point me in the right direction? I am testing locally at the moment right now so it is pretty easy to change things. I have access to the server code, client code and to the .keystore file.

Update

I was attempting to use one .keystore file for both the client and server but in hopes of simplifying my issues I have created server.keystore (see below) and client.truststore (see below). I am reasonably confident that the certicates are correct but if someone could verify I would be grateful.

server.keystore

hostname[username:/this/is/a/path][711]% keytool -list -keystore server.keystore -v
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: hostname
Creation date: Feb 4, 2010
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname
Issuer: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname
Serial number: 4b6b0ea7
Valid from: Thu Feb 04 13:15:03 EST 2010 until: Wed May 05 14:15:03 EDT 2010
Certificate fingerprints:
         MD5:  81:C0:3F:EC:AD:5B:7B:C4:DA:08:CC:D7:11:1F:1D:38
         SHA1: F1:78:AD:C8:D0:3A:4C:0C:9A:4F:89:C0:2A:2F:E2:E6:D5:13:96:40
         Signature algorithm name: SHA1withDSA
         Version: 3


*******************************************
*******************************************

client.truststore

hostname[username:/this/is/a/path][713]% keytool -list -keystore client.truststore -v
Enter keystore password:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: mykey
Creation date: Feb 4, 2010
Entry type: trustedCertEntry

Owner: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname
Issuer: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname
Serial number: 4b6b0ea7
Valid from: Thu Feb 04 13:15:03 EST 2010 until: Wed May 05 14:15:03 EDT 2010
Certificate fingerprints:
         MD5:  81:C0:3F:EC:AD:5B:7B:C4:DA:08:CC:D7:11:1F:1D:38
         SHA1: F1:78:AD:C8:D0:3A:4C:0C:9A:4F:89:C0:2A:2F:E2:E6:D5:13:96:40
         Signature algorithm name: SHA1withDSA
         Version: 3


*******************************************
*******************************************

Update

I thought it could be useful to include the entire exception:

javax.xml.soap.SOAPException: java.io.IOException: Could not transmit message
        at org.jboss.ws.core.soap.SOAPConnectionImpl.callInternal(SOAPConnectionImpl.java:115)
        at org.jboss.ws.core.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:66)
        at com.alcatel.tpapps.common.utils.SOAPClient.execute(SOAPClient.java:193)
        at com.alcatel.tpapps.common.utils.SOAPClient.main(SOAPClient.java:280)
Caused by: java.io.IOException: Could not transmit message
        at org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:192)
        at org.jboss.ws.core.client.SOAPRemotingConnection.invoke(SOAPRemotingConnection.java:77)
        at org.jboss.ws.core.soap.SOAPConnectionImpl.callInternal(SOAPConnectionImpl.java:106)
        ... 3 more
Caused by: org.jboss.remoting.CannotConnectException: Can not connect http client invoker. sun.security.validator.ValidatorException: No trusted certificate found.
        at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:368)
        at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:148)
        at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:141)
        at org.jboss.remoting.Client.invoke(Client.java:1858)
        at org.jboss.remoting.Client.invoke(Client.java:718)
        at org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:171)
        ... 5 more
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1584)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174)
        at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106)
        at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495)
        at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:877)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1116)
        at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1100)
        at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:402)
        at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170)
        at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:857)
        at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
        at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:288)
        ... 10 more
Caused by: sun.security.validator.ValidatorException: No trusted certificate found
        at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:304)
        at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:107)
        at sun.security.validator.Validator.validate(Validator.java:203)
        at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172)
        at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320)
        at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841)
        ... 22 more

解决方案

You would need to "establish trust" between your server and client (I'm assuming you only need to do server-side authentication). This is because you use self-signed certs. That involves importing your server's cert into the client trust store:

On the server side:

keytool -keystore <keystore file> -alias <alias> -export -file <certfilename>.cert

Copy the .cert file over to the client side and then:

keytool -keystore <truststore file> -alias <alias> -import -file <certfilename>.cert

这篇关于Keytool创建一个受信任的自签名证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆