【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实现单向认证
单项认证是客户端校验服务端,双向认证则服务端同时要校验客户端。
-
生成服务端sslServer.p12文件
keytool -genkey -v -alias sslServer -keyalg RSA -storetype PKCS12 -keystore E:\cert\sslServer.p12
-
将生成的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"; } }
-
配置https单项认证以前访问如下:
- 配置https单项认证以后访问如下:
则表明单向认证开启成功。
2、https实现单向认证
-
在服务端增加如下配置,表示服务端开启客户端校验
# 开启双向认证(客户端与服务端互相校验) 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
-
生成客户端证书sslClient.p12文件
keytool -genkey -v -alias sslClient -keyalg RSA -storetype PKCS12 -keystore E:\cert\sslClient.p12
-
导出客户端公钥sslClient.cer 文件
keytool -keystore E:\cert\sslClient.p12 -export -alias sslClient -file E:\cert\sslClient.cer
-
将客户端公钥导入服务端证书库
keytool -import -alias sslClient -v -file E:\cert\sslClient.cer -keystore D:\demo\src\main\resources\sslServer.p12
-
将服务端证书sslServer.p12文件和sslClient.p12提供给客户端
-
客户端实现双向认证代码:
@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的工作流程,是怎么具体实现数据安全呢?我下边贴个链接,感兴趣的小伙伴可以研究一下~
下一篇: VirtualBox多个虚拟机时网络设置
推荐阅读