Two-way authentication of https requests and SSL using the Jetty plug-in in eclipse

Keywords: SSL Jetty Java encoding

link

Full program source download, csdn not yet validated
1. Include both https and socket ssl test codes
2. All passwords are 123456

Environmental preparation

  • Install run-jetty-run plug-in in eclipse csdn download resource
  • java environment support, need to use keytool command

start

Generate server certificate

  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

 
Where: kserver.keystore is the keystore used by the service, server.crt is the certificate, and tclient.keystore is the trusted keystore used by the client

Specific note: here we use our own keystore to export the certificate directly, only available on our internal system. If you want to be available on the public network, you should generate crs to apply for the certificate from the ca

Generate client certificate

JKS mode

  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 Mode

  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

Configure the Jetty environment

Specific note: The jetty.xml file is configured separately here, because it is not possible to confirm where jetty's trusted certificate was found when doing two-way authentication, so the location is specified through the jetty.xml file.If you use one-way authentication, you can use jetty's ssl configuration directly.

<?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

Client Request Code

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();// Bidirectional Validation
        // client.initOneWay();//One-way validation
        client.doPost(path);
    }

    static {
        // Default ip address check passed
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;
            }
        });
    }

    /**
     * Bidirectional Validation
     */
    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);
        }
    }

    /**
     * One-way validation
     */
    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;
        }
        // Create URL Object
        URL myURL = new URL(path);
        // Create an HttpsURLConnection object and set its SSLSocketFactory object
        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

Service-side code

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

Verification

Start jetty server

Prompt the following information to verify that the server is up properly

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:8088
2016-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

Execute client ssl bidirectional request

If the request succeeds, the following information appears:
Client prompt:
Hello Client Post 
Server tip:
Server Post 
Hello Server

Posted by SecureMind on Thu, 07 May 2020 10:31:07 -0700