Approach 1: สร้าง SocketFactory ขึ้นมาใหม่
Class 1: NativeTrustManager
สร้าง TrustManager โดยที่ไม่มีการ throw Exception ออกมาเมื่อมีการทำ self-singed SSL certificate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; public class NaiveTrustManager implements X509TrustManager{ /** * Doesn't throw an exception, so this is how it approves a certificate. * @see javax.net.ssl.X509TrustManager#checkClientTrusted(java.security.cert.X509Certificate[], String) **/ public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } /** * Doesn't throw an exception, so this is how it approves a certificate. * @see javax.net.ssl.X509TrustManager#checkServerTrusted(java.security.cert.X509Certificate[], String) **/ public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { } /** * @see javax.net.ssl.X509TrustManager#getAcceptedIssuers() **/ public X509Certificate[] getAcceptedIssuers() { return null; // I've seen someone return new X509Certificate[ 0 ]; } } |
Class 2: สร้าง SelfSignedSSLSocketFactory ใหม่โดยจำทำการ accept self-signed certificate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | package etherdia.gen.util.ssl; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManager; import org.apache.log4j.Logger; public class SelfSignedSSLSocketFactory { private static SSLSocketFactory sslSocketFactory; private static Logger logger = Logger .getLogger(SelfSignedSSLSocketFactory .class); /** * Returns a SSL Factory instance that accepts all server certificates. * * SSLSocket sock = (SSLSocket) getSocketFactory.createSocket(host, 443); * * @return An SSL-specific socket factory. **/ public static final SSLSocketFactory getSocketFactory() { System.setProperty("javax.net.ssl.trustStore ", "org.jiramot.sslutils.NaiveTrustManager"); if (sslSocketFactory == null) { try { TrustManager[] tm = new TrustManager[] { new NaiveTrustManager() }; SSLContext context = SSLContext.getInstance("SSL"); context.init(new KeyManager[0], tm, new SecureRandom()); sslSocketFactory = (SSLSocketFactory) context .getSocketFactory(); } catch (KeyManagementException e) { logger.error("No SSL algorithm support: " + e.getMessage(), e); } catch (NoSuchAlgorithmException e) { logger.error( "Exception when setting up the Naive key management.", e); } } return sslSocketFactory; } } |
Approach 2: สร้าง Security Provider ใหม่โดย extends java.security.Provider โดยทำการแก้ไขให้ทำการสร้าง NativeTrustManager
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | import java.security.AccessController; import java.security.KeyStore; import java.security.PrivilegedAction; import java.security.Provider; import java.security.Security; import javax.net.ssl.ManagerFactoryParameters; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactorySpi; /** * Provides all secure socket factories, with a socket that ignores problems in * the chain of certificate trust. This is good for embedded applications that * just want the encryption aspect of SSL communication, without worrying too * much about validating the identify of the server at the other end of the * connection. In other words, this may leave you vulnerable to a * man-in-the-middle attack. */ public class NaiveTrustProvider extends Provider { /** The name of our algorithm **/ private static final String TRUST_PROVIDER_ALG = "NaiveTrustAlgorithm"; /** Need to refer to ourselves somehow to know if we're already registered **/ private static final String TRUST_PROVIDER_ID = "NaiveTrustProvider"; /** * Hook in at the provider level to handle libraries and 3rd party utilities * that use their own factory. Requires permission to execute * AccessController.doPrivileged, so this probably won't work in applets or * other high-security jvms **/ public NaiveTrustProvider() { super( TRUST_PROVIDER_ID, (double) 0.1, "NaiveTrustProvider (provides all secure socket factories by ignoring problems in the chain of certificate trust)"); AccessController.doPrivileged(new PrivilegedAction() { public Object run() { put("TrustManagerFactory." + NaiveTrustManagerFactory.getAlgorithm(), NaiveTrustManagerFactory.class.getName()); return null; } }); } /** * This is the only method the client code need to call. Yup, just put * NaiveTrustProvider.setAlwaysTrust() into your initialization code and * you're good to go * * @param enableNaiveTrustProvider * set to true to always trust (set to false it not yet * implemented) **/ public static void setAlwaysTrust(boolean enableNaiveTrustProvider) { if (enableNaiveTrustProvider) { Provider registered = Security.getProvider(TRUST_PROVIDER_ID); if (null == registered) { Security.insertProviderAt(new NaiveTrustProvider(), 1); Security.setProperty("ssl.TrustManagerFactory.algorithm", TRUST_PROVIDER_ALG); } } else { throw new UnsupportedOperationException( "Disable Naive trust provider not yet implemented"); } } /** * The factory for the NaiveTrustProvider **/ public final static class NaiveTrustManagerFactory extends TrustManagerFactorySpi { public NaiveTrustManagerFactory() { } protected void engineInit(ManagerFactoryParameters mgrparams) { } protected void engineInit(KeyStore keystore) { } /** * Returns a collection of trust managers that are naive. This * collection is just a single element array containing our * {@link NaiveTrustManager} class. **/ protected TrustManager[] engineGetTrustManagers() { // Returns a new array of just a single NaiveTrustManager. return new TrustManager[] { new NaiveTrustManager() }; } /** * Returns our "NaiveTrustAlgorithm" string. * * @return The string, "NaiveTrustAlgorithm" */ public static String getAlgorithm() { return TRUST_PROVIDER_ALG; } } } |
ที่มา SelfSignedCerts
