Https原理及实现 //to be continued

目录

1. Https原理及过程

...

2. Https服务端

3. Https客户端

3.1 客户端请求的java实现


import javax.net.ssl.HttpsURLConnection;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;

/**
 * 基于HttpsURLConnection实现客户端https请求
 *
 */
public class HttpsClientDemo {
    private static final String METHOD_GET = "GET";
    private static final String METHOD_POST = "POST";

    /**
     * doGet
     */
    private static void httpsGet(String url) throws NoSuchAlgorithmException, KeyManagementException, IOException {
        // 创建连接对象
        HttpsURLConnection connection = getHttpsURLConnection(url, METHOD_GET);
        connection.connect();
        System.out.println("cipersuit used:" + connection.getCipherSuite());

        // 读取连接响应内容
        getresponse(connection);
    }

    /**
     * doPost
     */
    private static void httpsPost(String url, String params) throws NoSuchAlgorithmException, IOException, KeyManagementException {
        // 创建连接对象
        HttpsURLConnection connection = getHttpsURLConnection(url, METHOD_POST);
        // 发送POST请求必须设置如下两行
        connection.setDoOutput(true);
        connection.setDoInput(true);
        connection.connect();

        // 获取URLConnection对象对应的输出流
        PrintWriter out = null;
        try {
            out = new PrintWriter(connection.getOutputStream());
            // 发送请求参数
            out.print(params);
            out.flush();
        } finally {
            if (out != null) {
                out.close();
            }
        }
        getresponse(connection);
    }

    /**
     * 读取连接响应内容
     */
    private static void getresponse(HttpsURLConnection connection) throws IOException {

        BufferedReader br = null;
        try {
            br = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String inputLine;
            StringBuilder sb = new StringBuilder();
            while ((inputLine = br.readLine()) != null) {
                sb.append(inputLine);
            }
            System.out.println(sb.toString());
            System.out.println("responseMsg:" + connection.getResponseMessage() + "; responseCode:" + connection.getResponseCode());
        } finally {
            if (br != null) {
                br.close();
            }
        }
    }

    /**
     * 获取连接对象
     */
    private static HttpsURLConnection getHttpsURLConnection(String url, String method) throws IOException, NoSuchAlgorithmException, KeyManagementException {
        URL myUrl = new URL(url);
        // 创建连接对象
        HttpsURLConnection connection = (HttpsURLConnection) myUrl.openConnection();
        connection.setRequestMethod(method);
        // 设置SSLSocketFactory对象(若不指定算法套,getSslContext().getSocketFactory()即可)
        connection.setSSLSocketFactory(new MySSLSocketFactory());
        // 验证hostname,全部允许
        connection.setHostnameVerifier((hostname, sslSession) -> true);

        // 设置通用请求属性
        connection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36");
        connection.setRequestProperty("Connection", "Keep-Alive");
        connection.setRequestProperty("Charset", "UTF-8");

        return connection;
    }

    public static void main(String[] args) throws Exception {
        String url = "https://***";

        httpsGet(url);
//        httpsPost(url, "username=admin&password=admin@1234&forceLogin=false");
    }
}

如果是需要设置客户端算法套,可以通过继承SSLSocketFactory重写其createSocket()方法,自行设置SSL算法套。

import javax.net.ssl.*;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * 重写createSocket方法,设置算法套
 */
public class MySSLSocketFactory extends SSLSocketFactory {
    private static final String[] cipherSuites = new String[]{
            "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
            "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"};

    private static SSLContext sslContext = null;

    // 设置算法套
    private void setSSLParams(SSLSocket sslSocket) {
        sslSocket.setUseClientMode(true);
        sslSocket.setEnabledCipherSuites(cipherSuites);
    }

    /**
     * 创建SSLContext对象,使用默认信任管理器初始化
     */
    private static SSLContext getSslContext() {
        if (sslContext == null) {
            try {
                sslContext = SSLContext.getInstance("TLSv1.2");
                sslContext.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()}, new SecureRandom());
            } catch (NoSuchAlgorithmException | KeyManagementException e) {
                e.printStackTrace();
            }
            SSLContext.setDefault(sslContext);
        }
        return sslContext;
    }

    @Override
    public String[] getDefaultCipherSuites() {
        return cipherSuites;
    }

    @Override
    public String[] getSupportedCipherSuites() {
        return cipherSuites;
    }

    @Override
    public Socket createSocket(Socket socket, String host, int port, boolean b) throws IOException {
        SSLSocket sslSocket = (SSLSocket) getSslContext().getSocketFactory().createSocket(socket, host, port, b);
        setSSLParams(sslSocket);
        return sslSocket;
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException {
        SSLSocket sslSocket = (SSLSocket) getSslContext().getSocketFactory().createSocket(host, port);
        setSSLParams(sslSocket);
        return sslSocket;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {
        SSLSocket sslSocket = (SSLSocket) getSslContext().getSocketFactory().createSocket(host, port, localHost, localPort);
        setSSLParams(sslSocket);
        return sslSocket;
    }

    @Override
    public Socket createSocket(InetAddress host, int port) throws IOException {
        SSLSocket sslSocket = (SSLSocket) getSslContext().getSocketFactory().createSocket(host, port);
        setSSLParams(sslSocket);
        return sslSocket;
    }

    @Override
    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {
        SSLSocket sslSocket = (SSLSocket) getSslContext().getSocketFactory().createSocket(address, port, localAddress, localPort);
        setSSLParams(sslSocket);
        return sslSocket;
    }


    /**
     * SSL信任管理类
     */
    private static class DefaultTrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

    }

}

猜你喜欢

转载自www.cnblogs.com/eaglediao/p/9465537.html