eclipse中使用Jetty插件实现https请求与SSL双向验证

来源:互联网 发布:飞哥软件 编辑:程序博客网 时间:2024/06/06 13:13

链接

完整程序源码下载,csdn还没验证通过 
1. 包含https和socket两种ssl测试代码 
2. 所有密码均为123456

环境准备

  • eclipse中安装run-jetty-run插件 csdn下载资源
  • java环境支持,需要使用keytool命令

开始

生成服务器证书

  1. keytool -genkey -alias serverkey -keyalg RSA -keystore kserver.keystore
  2. keytool -export -alias serverkey -keystore kserver.keystore -rfc -file server.crt
  3. keytool -import -alias serverkey -file server.crt -keystore tclient.keystore

这里写图片描述 
其中:kserver.keystore就是服务使用的keystore,server.crt是证书,tclient.keystore是给客户端使用的信任keystore

特别说明:这里我们使用自己的keystore直接导出证书,仅在自己的内部系统可用,如果希望在公网可用,应生成crs向ca申请证书

生成客户端证书

JKS方式

  1. keytool -genkey -alias clientKey -keystore kclient.keystore
  2. keytool -export -alias clientKey -keystore kclient.keystore -file client.crt
  3. keytool -import -alias clientKey -file client.crt -keystore tserver.keystore

PKCS12方式

  1. keytool -genkeypair -alias clientkey -keyalg RSA -storetype PKCS12 -keystore client.p12
  2. keytool -export -alias clientKey -keystore client.p12 -storetype PKCS12 -rfc -file client.crt
  3. keytool -import -alias clientKey -file client.crt -keystore tserver.keystore

配置Jetty环境

这里写图片描述

特别说明:这里单独配置了jetty.xml文件,因为无法确认jetty在做双向验证时候的可信证书从哪里找的,所以通过jetty.xml文件来指定位置。如果使用单向验证,那么可以直接使用jetty的ssl配置即可。

<?xml version="1.0"?><!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd"><Configure id="Server" class="org.eclipse.jetty.server.Server">    <Call name="addConnector">     <Arg>       <New class="org.eclipse.jetty.server.ssl.SslSelectChannelConnector">         <Arg>           <New class="org.eclipse.jetty.http.ssl.SslContextFactory">             <Set name="keyStore">D:/workspace/SSLServer/src/ssl/keystore/server/kserver.keystore</Set>             <Set name="keyStorePassword">123456</Set>             <Set name="keyManagerPassword">123456</Set>             <!-- JSK -->             <Set name="trustStore">D:/workspace/SSLServer/src/ssl/keystore/client/tserver.keystore</Set>             <!-- PKCS12 -->             <!--<Set name="trustStore">D:/workspace/SSLServer/src/ssl/keystore/pk12/tserver.keystore</Set>-->             <Set name="trustStorePassword">123456</Set>             <Set name="needClientAuth">true</Set>           </New>         </Arg>         <Set name="port">8443</Set>         <Set name="maxIdleTime">30000</Set>       </New>     </Arg>   </Call></Configure>
  • 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

客户端请求代码

package ssl.https;import java.io.BufferedReader;import java.io.FileInputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.URL;import java.security.KeyStore;import java.security.SecureRandom;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.KeyManagerFactory;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSession;import javax.net.ssl.SSLSocketFactory;import javax.net.ssl.TrustManagerFactory;public class SSLSayClient {    private static final String CLIENT_KEY_STORE_PASSWORD = "123456";    private static final String CLIENT_TRUST_KEY_STORE_PASSWORD = "123456";    private SSLSocketFactory ssLSocketFactory;    public static void main(String[] args) throws Exception {        String path = "https://192.168.1.83:8443/SSLServer/say";        SSLSayClient client = new SSLSayClient();        client.init();// 双向验证        // client.initOneWay();// 单向验证        client.doPost(path);    }    static {        // 默认ip地址校验通过        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {            @Override            public boolean verify(String hostname, SSLSession session) {                return true;            }        });    }    /**     * 双向验证     */    public void init() {        try {            SSLContext ctx = SSLContext.getInstance("SSL");            KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");            KeyStore ks = KeyStore.getInstance("JKS");// JKS            // KeyStore ks = KeyStore.getInstance("PKCS12");// PKCS12            KeyStore tks = KeyStore.getInstance("JKS");            // JSK            ks.load(new FileInputStream("D:/workspace/SSLServer/src/ssl/keystore/client/kclient.keystore"), CLIENT_KEY_STORE_PASSWORD.toCharArray());            // PKCS12            // ks.load(new            // FileInputStream("D:/workspace/SSLServer/src/ssl/keystore/pk12/client.p12"),            // CLIENT_KEY_STORE_PASSWORD.toCharArray());            tks.load(new FileInputStream("D:/workspace/SSLServer/src/ssl/keystore/server/tclient.keystore"), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());            kmf.init(ks, CLIENT_KEY_STORE_PASSWORD.toCharArray());            tmf.init(tks);            ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), new SecureRandom());            ssLSocketFactory = ctx.getSocketFactory();        } catch (Exception e) {            System.out.println(e);        }    }    /**     * 单向验证     */    public void initOneWay() {        try {            SSLContext ctx = SSLContext.getInstance("SSL");            TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");            KeyStore tks = KeyStore.getInstance("JKS");            tks.load(new FileInputStream("D:/workspace/SSLServer/src/ssl/keystore/server/tclient.keystore"), CLIENT_TRUST_KEY_STORE_PASSWORD.toCharArray());            tmf.init(tks);            ctx.init(null, tmf.getTrustManagers(), new SecureRandom());            ssLSocketFactory = ctx.getSocketFactory();        } catch (Exception e) {            System.out.println(e);        }    }    /**     * POST     */    public void doPost(String path) throws Exception {        if (ssLSocketFactory == null) {            System.out.println("ERROR");            return;        }        // 创建URL对象        URL myURL = new URL(path);        // 创建HttpsURLConnection对象,并设置其SSLSocketFactory对象        HttpsURLConnection httpsConn = (HttpsURLConnection) myURL.openConnection();        httpsConn.setSSLSocketFactory(ssLSocketFactory);        String encoding = "UTF-8";        byte[] data = "Hello Server".getBytes(encoding);        httpsConn.setRequestMethod("POST");        httpsConn.setDoOutput(true);        httpsConn.setRequestProperty("Content-Type", "application/json; charset=" + encoding);        httpsConn.setRequestProperty("Content-Length", String.valueOf(data.length));        OutputStream outStream = httpsConn.getOutputStream();        outStream.write(data);        outStream.flush();        outStream.close();        BufferedReader a = new BufferedReader(new InputStreamReader(httpsConn.getInputStream(), "UTF-8"));        String line = null;        while ((line = a.readLine()) != null) {            System.out.println(line);        }    }}
  • 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
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131

服务端代码

package ssl.https;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStream;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class Say extends HttpServlet {    private static final long serialVersionUID = -840442603737824400L;    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        System.out.println("Server Get");        String encoding = "UTF-8";        response.setContentType("application/json; charset=" + encoding);        OutputStream outStream = response.getOutputStream();        outStream.write("Hello Client Get".getBytes(encoding));        outStream.flush();        outStream.close();    }    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        System.out.println("Server Post");        BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));        String line = null;        while ((line = br.readLine()) != null) {            System.out.println(line);        }        String encoding = "UTF-8";        response.setContentType("application/json; charset=" + encoding);        OutputStream outStream = response.getOutputStream();        outStream.write("Hello Client Post".getBytes(encoding));        outStream.flush();        outStream.close();    }}
  • 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

验证

启动jetty服务器

提示以下信息,证明服务器启动正常

2016-02-23 10:38:52.628:INFO:oejsh.ContextHandler:started o.e.j.w.WebAppContext{/SSLServer,[file:/D:/workspace/SSLServer/WebContent/]}2016-02-23 10:38:52.710:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:80882016-02-23 10:38:52.896:INFO:oejus.SslContextFactory:Enabled Protocols [SSLv2Hello, SSLv3, TLSv1] of [SSLv2Hello, SSLv3, TLSv1]2016-02-23 10:38:52.899:INFO:oejs.AbstractConnector:Started SslSelectChannelConnector@0.0.0.0:8443
  • 1
  • 2
  • 3
  • 4

执行客户端ssl双向请求

如果请求成功,将出现如下信息: 
客户端提示: 
Hello Client Post 
服务端提示: 
Server Post 
Hello Server