java实现https服务器

说明

java实现https服务器,处理证书需要额外代码

证书

需要到阿里云等平台申请 pfx 证书

修改host文件

由于 pfx 证书与域名相关,所以需要改host文件,访问该域名时,实际访问的是本机 127.0.0.1 的网址

代码

package test;

import javax.net.ssl.*;
import java.io.*;
import java.net.InetSocketAddress;
import java.security.*;
import java.security.cert.CertificateException;

/**
 * 实现 https server
 * 关键:pfx证书,而且必须使用与证书匹配的域名访问,需要改host
 */
public class Server {
    SSLContext context;
    public SSLContext init(String pfxPath, String password) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException, KeyManagementException {

        KeyStore keyStore = KeyStore.getInstance("PKCS12");
        InputStream instream = new FileInputStream(new File(pfxPath));
        try {
            keyStore.load(instream, password.toCharArray());
        } finally {
            instream.close();
        }
        context = SSLContext.getInstance("SSL");
        KeyManagerFactory kmfactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        kmfactory.init(keyStore, password != null ? password.toCharArray() : null);
        KeyManager[] keymanagers = kmfactory.getKeyManagers();
        context.init(keymanagers, null, null);
        return context;
    }
    public void connect(String ip,int port) throws IOException, NoSuchAlgorithmException, KeyManagementException {
        SSLServerSocketFactory serverSocketFactory = context.getServerSocketFactory();

        SSLServerSocket serverSocket = (SSLServerSocket)serverSocketFactory.createServerSocket();
        serverSocket.bind(new InetSocketAddress(ip,port));
//        不需要双向认证,可以不加此代码
        serverSocket.setNeedClientAuth(false);
        System.out.println("启动成功!");
        while (true) {
            // 服务器端套接字进入阻塞状态,等待来自客户端的连接请求
            SSLSocket socket = (SSLSocket) serverSocket.accept();
            new Thread(new Handle(socket)).start();
        }

    }
    public static void main(String[] args) throws Exception {
        Server server = new Server();
        server.init("./cert/8547669_www.malaoshi.top.pfx","UWvPWTb0");
        server.connect("127.0.0.1",8443);

    }
}
package test;

import javax.net.ssl.SSLSocket;
import java.io.*;

public class Handle implements Runnable{
    private SSLSocket socket;
    public Handle(SSLSocket socket){
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            InputStream inputStream = socket.getInputStream();
            OutputStream outputStream = socket.getOutputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(inputStream,"utf-8"));
            String line;
            while ( (line = br.readLine()) != null){
                if("".equals(line)){
                    break;
                }
                System.out.println(line);
            }
            System.out.println(111);
            PrintWriter pw = new PrintWriter(outputStream);
            pw.write("HTTP/1.1 200 OK\r\n");
            pw.write("Content-Type: text/html; charset=utf-8\r\n");
            pw.write("\r\n");
            pw.write("\r\n");
            pw.flush();
            pw.write("哈哈");
            pw.write("\r\n");
            pw.flush();
            socket.close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

详见:
https://blog.csdn.net/chencai123654/article/details/98367460