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

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";
        }
    }

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

  4. 配置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();
            }
        }
    }

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

    总结

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

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值