欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【springboot】配置实现https单项认证和双向认证

程序员文章站 2022-04-11 10:22:52
...

1、什么是https 

HTTPS其实是HTTP + SSL,S的含义也就是Secure Socket Layer(简称SSL)。

下边简单介绍一下SSL:

SSL是用于在web上实现加密最广泛使用的协议。SSL为用于Internet通信的标准TCP / IP通信协议提供安全增强。SSL添加在标准的TCP/IP协议中的传输层和应用层之间。HTTP是使用SSL协议最常见的应用,即Internet网页的协议。SSL使用加密过程的组合提供了互联网通信安全。

2、https实现单向认证

单项认证是客户端校验服务端,双向认证则服务端同时要校验客户端。

  1. 生成服务端sslServer.p12文件

    keytool -genkey -v -alias sslServer -keyalg RSA -storetype PKCS12 -keystore E:\cert\sslServer.p12

  2. 将生成的sslServer.p12证书文件放到resource目录下,对外提供接口,配置application.properties文件

    server.port=9000
    server.address=127.0.0.1
    server.ssl.key-store=classpath:sslServer.p12
    server.ssl.key-store-password=123456
    server.ssl.key-alias=sslServer
    server.ssl.keyStoreType=JKS
    @RestController
    @RequestMapping("/demo")
    public class HttpsController {
    ​
        @GetMapping("/getResponse")
        public String getHttpsResponse(){
            return "hello";
        }
    }

    【springboot】配置实现https单项认证和双向认证

  3. 配置https单项认证以前访问如下:

    【springboot】配置实现https单项认证和双向认证

  4. 配置https单项认证以后访问如下:

 

【springboot】配置实现https单项认证和双向认证

则表明单向认证开启成功。

2、https实现单向认证

  1. 在服务端增加如下配置,表示服务端开启客户端校验

    # 开启双向认证(客户端与服务端互相校验)
    server.ssl.trust-store=classpath:sslServer.p12
    server.ssl.trust-store-password=123456
    server.ssl.client-auth=need
    server.ssl.trust-store-type=JKS
    server.ssl.trust-store-provider=SUN

     

  2. 生成客户端证书sslClient.p12文件

     keytool -genkey -v -alias sslClient -keyalg RSA -storetype PKCS12 -keystore E:\cert\sslClient.p12

  3. 出客户端公钥sslClient.cer 文件

    keytool -keystore E:\cert\sslClient.p12 -export -alias sslClient -file E:\cert\sslClient.cer

  4. 将客户端公钥导入服务端证书库

    keytool -import -alias sslClient -v -file E:\cert\sslClient.cer -keystore D:\demo\src\main\resources\sslServer.p12

  5. 将服务端证书sslServer.p12文件和sslClient.p12提供给客户端

  6. 客户端实现双向认证代码:

    @SpringBootApplication
    public class ClientApplication {
    ​
        public static void main(String[] args) {
            SpringApplication.run(ClientApplication.class, args);
            try {
                getHKVesselTrip();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    ​
        public static void getHKVesselTrip() throws Exception {
            // 客户端证书类型
            KeyStore clientStore = KeyStore.getInstance("PKCS12");
            // 加载客户端证书,即自己的私钥
            clientStore
                    .load(new FileInputStream("E:\\cert\\sslClient.p12"),
                            "123456".toCharArray());
            // 创建**管理工厂实例
            KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
            // 初始化客户端**库
            kmf.init(clientStore, "123456".toCharArray());
            KeyManager[] kms = kmf.getKeyManagers();
            // 创建信任库管理工厂实例
            TrustManagerFactory tmf = TrustManagerFactory
                    .getInstance(TrustManagerFactory.getDefaultAlgorithm());
            // 信任库类型
            KeyStore trustStore = KeyStore.getInstance("JKS");
            // 加载信任库,即服务端公钥
            trustStore.load(new FileInputStream("D:\\demo\\src\\main\\resources\\sslServer.p12"),
                    "123456".toCharArray());
            // 初始化信任库
            tmf.init(trustStore);
            TrustManager[] tms = tmf.getTrustManagers();
            // 建立TLS连接
            SSLContext sslContext = SSLContext.getInstance("TLS");
            // 初始化SSLContext
            sslContext.init(kms, tms, new SecureRandom());
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
            try {
                HttpGet httpget = new HttpGet("https://127.0.0.1:9000/demo/getResponse");
                System.out.println("executing request" + httpget.getRequestLine());
                CloseableHttpResponse response = httpclient.execute(httpget);
                try {
                    HttpEntity entity = response.getEntity();
                    if (entity != null) {
                        System.out.println(EntityUtils.toString(entity));
                    }
                } finally {
                    response.close();
                }
            } finally {
                httpclient.close();
            }
        }
    }

    打印响应信息如下,表明双向认证成功:

    【springboot】配置实现https单项认证和双向认证

    总结

    其实https在咱们应用中很常见,也只是实现了简单的单项认证,只需要校验客户端的身份就好了,其实网银的U盾就用到双向认证,出了校验服务端意外,服务端会校验客户端的身份,保证数据安全。其实还有设计到SSL的工作流程,是怎么具体实现数据安全呢?我下边贴个链接,感兴趣的小伙伴可以研究一下~

相关标签: 互联网