Keytool 创建受信任的自签名证书
我正在尝试使用 (java) keytool 创建一个自签名证书,但是当我尝试使用它时,我得到了以下异常(整个异常请参见底部).
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);
(来源)
但我对这种解决方案不感兴趣,因为我认为它会造成安全漏洞.(如果我错了,请纠正我).
But I am not interested in this solutions because I think that it creates a security hole. (please correct me if I am wrong).
谁能指出我正确的方向?我现在正在本地测试,所以很容易改变.我可以访问服务器代码、客户端代码和 .keystore 文件.
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.
我试图为客户端和服务器使用一个 .keystore 文件,但为了简化我的问题,我创建了 server.keystore(见下文)和 client.truststore(见下文).我有理由相信这些证书是正确的,但如果有人可以验证,我将不胜感激.
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:
在服务器端:
keytool -keystore <keystore file> -alias <alias> -export -file <certfilename>.cert
将 .cert 文件复制到客户端,然后:
Copy the .cert file over to the client side and then:
keytool -keystore <truststore file> -alias <alias> -import -file <certfilename>.cert
相关文章