If you have ever tried to connect to https by Java, chances are you will hit such exception:
Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found
normal solution is to import cert w/ keytool, which drives lazybones like me mad.
but you can live w/o it. hereunder another easier solution:
package com.xxx.yyy.ssl;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.apache.log4j.Logger;
import com.sun.net.ssl.HostnameVerifier;
import com.sun.net.ssl.HttpsURLConnection;
public class SSlTrustManagerTool {
protected static final Logger logger = Logger.getLogger(SSlTrustManagerTool.class);
private SSlTrustManagerTool() {
}
/**
* When reading the content from a HTTPS connection, a
* <code>javax.net.ssl.SSLException:
* untrusted server cert chain</code>
* can be thrown for untrusted servers. To force reading from such untrusted
* servers, this method installs a 'all-trustung' trust manager that returns
* 'true' for all servers.
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*
* @throws Exception
* if installation of the new trust manager failed.
*/
public static void trustHttpsCertificates() throws NoSuchAlgorithmException, KeyManagementException {
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
// Create a trust manager that does not validate certificate chains:
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
logger.debug("getAcceptedIssuers");
return null;
}
public void checkServerTrusted(X509Certificate[] certs,
String authType) throws CertificateException {
logger.debug("checkServerTrusted");
return;
}
public void checkClientTrusted(X509Certificate[] certs,
String authType) throws CertificateException {
logger.debug("checkClientTrusted");
return;
}
} // X509TrustManager
};// TrustManager[]
// Install the all-trusting trust manager:
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
public boolean verify(String hostname, String session) {
logger.debug(hostname + " " + session + " is accepted!");
return true;
}
});
}// trustHttpsCertificates()
}
With this class, you won't need to import any cert. Just run the static method before starting to connect any SSL server.
Note: The code is originally provided by somebody on Sun's forum. But the original code doesn't work for me. So I hacked it and finally get it work.