WSImport over SSL 与假 (开发) 证书.



>最近我花了几个小时试图让WSImport在通过HTTPS托管的Web服务上工作,使用假证书(开发部署)。

我尝试使用Windows 版本的 wsimport.exe,来自 Java 8 jdk。

我指定了选项 -XdisableSSLHostnameVerification ,但它一直在抱怨错误的证书。确实,证书无效,但在开发环境中应该是可以接受的。

我没有找到简单的方法来使wsimport跳过证书检查。

最后我得到了一个解决方案,使用包装类。

我认为分享解决方案是有意义的。希望它能为更好的目的节省一些人的时间。

解决方案(假设 java 安装在 c:Program FilesJavajdk1.8.0_40 中):

  1. 如何编译

    "c:Program FilesJavajdk1.8.0_40binjavac" -cp "c:Program FilesJavajdk1.8.0_40libtools.jar" WSImportSSLByPass.java

  2. 如何使用

    "c:Program FilesJavajdk1.8.0_40binjava" -cp "c:Program FilesJavajdk1.8.0_40libtools.jar";. WSImportSSLByPass %wsimport args%

  3. 代码

待投入WSImportSSLByPass.java

    import java.security.KeyManagementException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    import java.security.cert.X509Certificate;
    import javax.net.ssl.HostnameVerifier;
    import javax.net.ssl.HttpsURLConnection;
    import javax.net.ssl.SSLContext;
    import javax.net.ssl.SSLSession;
    import javax.net.ssl.SSLSocketFactory;
    import javax.net.ssl.TrustManager;
    import javax.net.ssl.X509TrustManager;
    public class WSImportSSLByPass {
        public static void main(String[] args) throws Throwable{
            configureBypassSSL();
            com.sun.tools.internal.ws.WsImport.main(args);
        }
        private static void configureBypassSSL() throws NoSuchAlgorithmException,
                KeyManagementException {
            SSLContext ssl_ctx = SSLContext.getInstance("SSL");
            TrustManager[] trust_mgr = get_trust_mgr();
            ssl_ctx.init(null, // key manager
                    trust_mgr, // trust manager
                    new SecureRandom()); // random number generator
            SSLSocketFactory sf = ssl_ctx.getSocketFactory();
            HttpsURLConnection.setDefaultSSLSocketFactory(sf);
            HttpsURLConnection.setDefaultHostnameVerifier(new DummyHostVerifier());
        }
        private static TrustManager[] get_trust_mgr() {
            TrustManager[] certs = new TrustManager[] { new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                public void checkClientTrusted(X509Certificate[] certs, String t) {
                }
                public void checkServerTrusted(X509Certificate[] certs, String t) {
                }
            } };
            return certs;
        }
    }
    class DummyHostVerifier implements HostnameVerifier {
        public boolean verify(String name, SSLSession sess) {
            return true;
        }
    }

在 2 路 SSL 握手的情况下,我们可以像这样修改 WSImportSSLByPass 类

    import com.sun.tools.internal.ws.WsImport;
public class OCBWSImport {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws Throwable {
        // TODO code application logic here
        //System.setProperty("javax.net.ssl.trustStore", "C:\Program Files\Java\jdk1.8.0_131\jre\lib\security\cacerts");
        //System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
        //System.setProperty("javax.net.ssl.keyStoreType", "pkcs12");
        //Certificate for 2-way handshake
        System.setProperty("javax.net.ssl.keyStore", "D:\tuanpa\yourp12file.p12");
        System.setProperty("javax.net.ssl.keyStorePassword", "password of p12 file");
        //Hostname checking bypass
        javax.net.ssl.HttpsURLConnection.setDefaultHostnameVerifier(
                new javax.net.ssl.HostnameVerifier() {
            public boolean verify(String hostname,
                    javax.net.ssl.SSLSession sslSession) {
                //return hostname.equals("192.168.1.10");
                return true;
            }
        });
        WsImport.main(args);
    }
}

最新更新