J
Jakekeke
Dear All,
I use JSSE to implement a proxy server which support http/https.
However, I find my code can't support some secure site which provide a
certificate which doesn't signed by CA.
and here is the error message:
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: No trusted certificate
found
at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SunJSSE_ax.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.j(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(DashoA12275)
at Proxy.SSLNegotiation.startNegotiation(SSLNegotiation.java:101)
at Proxy.SSLProxyProcess.makeNegotiation(SSLProxyProcess.java:383)
at Proxy.SSLProxyProcess.run(SSLProxyProcess.java:83)
at Proxy.ProxyProcess.run(ProxyProcess.java:107)
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:202)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(DashoA12275)
at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(DashoA12275)
... 10 more
java.net.SocketException: Socket is closed
at java.net.Socket.setSoTimeout(Socket.java:920)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.setSoTimeout(DashoA12275)
at Proxy.HttpResp.<init>(HttpResp.java:53)
at Proxy.SSLProxyProcess.makeNegotiation(SSLProxyProcess.java:385)
at Proxy.SSLProxyProcess.run(SSLProxyProcess.java:83)
at Proxy.ProxyProcess.run(ProxyProcess.java:107)
what should i do to accept the self-sign certificate?
Thank,
Jake
Here is my code.
package Proxy;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
public class SSLNegotiation {
private Socket socket = null;
private String host = null;
private int port;
private String keyStore = null;
private char keyStorePass[] = null;
private char keyPassword[] = null;
private String sslContextInst = null;
private String keyStoreInst = null;
private String keyManagerFactoryInst = null;
private String trustManagerFactoryInst = null;
public SSLNegotiation(Socket socket) {
this.socket = socket;
host = socket.getInetAddress().getHostName();
port = socket.getPort();
}
public SSLNegotiation(String host, int port) {
this.host = host;
this.port = port;
}
public SSLNegotiation(Socket socket, String host, int port) {
this.socket = socket;
this.host = host;
this.port = port;
}
public void importKeyStore(String ks, String ksp) {
importKeyStore(ks, ksp, ksp);
}
public void importKeyStore(String ks, String ksp, String kp) {
keyStore = ks;
keyStorePass = ksp.toCharArray();
keyPassword = kp.toCharArray();
}
public void setInstance(String content, String ks, String kmf, String
tmf) {
sslContextInst = content;
keyStoreInst = ks;
keyManagerFactoryInst = kmf;
trustManagerFactoryInst = tmf;
}
public Socket startNegotiation(boolean connectServer) {
KeyStore ks = null;
KeyManagerFactory kmf = null;
SSLContext sslContext = null;
SSLSocket sslSocket = null;
try {
ks = KeyStore.getInstance(keyStoreInst);
ks.load(this.getClass().getResourceAsStream(keyStore),
keyStorePass);
kmf = KeyManagerFactory.getInstance(keyManagerFactoryInst);
kmf.init(ks, keyPassword);
sslContext = SSLContext.getInstance(sslContextInst);
if (trustManagerFactoryInst == null)
sslContext.init(kmf.getKeyManagers(), null, null);
else {
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(trustManagerFactoryInst);
tmf.init(ks);
sslContext.init(kmf.getKeyManagers(),
tmf.getTrustManagers(),
new java.security.SecureRandom());
}
SSLSocketFactory factory = sslContext.getSocketFactory();
if (socket != null)
sslSocket = (SSLSocket) factory.createSocket(socket, host, port,
false);
else
sslSocket = (SSLSocket) factory.createSocket(host, port);
sslSocket.setUseClientMode(connectServer);
sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
if (connectServer)
sslSocket.startHandshake();
} catch (UnknownHostException uhe) {
uhe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
return sslSocket;
}
}
}
I use JSSE to implement a proxy server which support http/https.
However, I find my code can't support some secure site which provide a
certificate which doesn't signed by CA.
and here is the error message:
javax.net.ssl.SSLHandshakeException:
sun.security.validator.ValidatorException: No trusted certificate
found
at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SunJSSE_az.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SunJSSE_ax.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.j(DashoA12275)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(DashoA12275)
at Proxy.SSLNegotiation.startNegotiation(SSLNegotiation.java:101)
at Proxy.SSLProxyProcess.makeNegotiation(SSLProxyProcess.java:383)
at Proxy.SSLProxyProcess.run(SSLProxyProcess.java:83)
at Proxy.ProxyProcess.run(ProxyProcess.java:107)
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:202)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(DashoA12275)
at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(DashoA12275)
... 10 more
java.net.SocketException: Socket is closed
at java.net.Socket.setSoTimeout(Socket.java:920)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.setSoTimeout(DashoA12275)
at Proxy.HttpResp.<init>(HttpResp.java:53)
at Proxy.SSLProxyProcess.makeNegotiation(SSLProxyProcess.java:385)
at Proxy.SSLProxyProcess.run(SSLProxyProcess.java:83)
at Proxy.ProxyProcess.run(ProxyProcess.java:107)
what should i do to accept the self-sign certificate?
Thank,
Jake
Here is my code.
package Proxy;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;
public class SSLNegotiation {
private Socket socket = null;
private String host = null;
private int port;
private String keyStore = null;
private char keyStorePass[] = null;
private char keyPassword[] = null;
private String sslContextInst = null;
private String keyStoreInst = null;
private String keyManagerFactoryInst = null;
private String trustManagerFactoryInst = null;
public SSLNegotiation(Socket socket) {
this.socket = socket;
host = socket.getInetAddress().getHostName();
port = socket.getPort();
}
public SSLNegotiation(String host, int port) {
this.host = host;
this.port = port;
}
public SSLNegotiation(Socket socket, String host, int port) {
this.socket = socket;
this.host = host;
this.port = port;
}
public void importKeyStore(String ks, String ksp) {
importKeyStore(ks, ksp, ksp);
}
public void importKeyStore(String ks, String ksp, String kp) {
keyStore = ks;
keyStorePass = ksp.toCharArray();
keyPassword = kp.toCharArray();
}
public void setInstance(String content, String ks, String kmf, String
tmf) {
sslContextInst = content;
keyStoreInst = ks;
keyManagerFactoryInst = kmf;
trustManagerFactoryInst = tmf;
}
public Socket startNegotiation(boolean connectServer) {
KeyStore ks = null;
KeyManagerFactory kmf = null;
SSLContext sslContext = null;
SSLSocket sslSocket = null;
try {
ks = KeyStore.getInstance(keyStoreInst);
ks.load(this.getClass().getResourceAsStream(keyStore),
keyStorePass);
kmf = KeyManagerFactory.getInstance(keyManagerFactoryInst);
kmf.init(ks, keyPassword);
sslContext = SSLContext.getInstance(sslContextInst);
if (trustManagerFactoryInst == null)
sslContext.init(kmf.getKeyManagers(), null, null);
else {
TrustManagerFactory tmf =
TrustManagerFactory.getInstance(trustManagerFactoryInst);
tmf.init(ks);
sslContext.init(kmf.getKeyManagers(),
tmf.getTrustManagers(),
new java.security.SecureRandom());
}
SSLSocketFactory factory = sslContext.getSocketFactory();
if (socket != null)
sslSocket = (SSLSocket) factory.createSocket(socket, host, port,
false);
else
sslSocket = (SSLSocket) factory.createSocket(host, port);
sslSocket.setUseClientMode(connectServer);
sslSocket.setEnabledCipherSuites(sslSocket.getSupportedCipherSuites());
if (connectServer)
sslSocket.startHandshake();
} catch (UnknownHostException uhe) {
uhe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
return sslSocket;
}
}
}