javascript
Spring Boot文档阅读笔记-how-to-implement-2-way-ssl-using-spring-boot
two-way-ssl需要12次握手(除去TCP的三次握手),如下圖:
?
雙向認證過程:
1.客戶端發送ClientHello消息,告訴服務端要使用SSL。
2.客戶端發送ServerHello的響應,告訴客戶端使用SSL。
3.服務端發送證書給客戶端;
4.服務端發送發送數據,要求客戶端發送證書;
5.此時客戶端與服務端招呼已經結束;
6.客戶端發送自己的證書給服務端(客戶端認證服務端證書成功);
7.客戶端發送session key(使用服務端公鑰加密);
8.客戶端發送一個CertificateVerify消息讓服務器知道它擁有發送證書;
9.客戶端發送自己支持的通道加密套給服務端;
10.客戶端要服務端從中選著一個;
11.服務端選擇一個加密套,并且告訴客戶端,我選擇了這個;
12.服務端發送認證完成。
使用keytool生成證書:
keytool -genkeypair -alias client-app -keyalg RSA -keysize 2048 -storetype JKS -keystore client-app.jks -validity 3650 -ext SAN=dns:localhost,ip:127.0.0.1 keytool -genkeypair -alias server-app -keyalg RSA -keysize 2048 -storetype JKS -keystore server-app.jks -validity 3650 -ext SAN=dns:localhost,ip:127.0.0.1 keytool -export -alias client-app -file client-app.crt -keystore client-app.jks keytool -export -alias server-app -file server-app.crt -keystore server-app.jks keytool -import -alias server-app -file server-app.crt -keystore client-app.jks keytool -import -alias client-app -file client-app.crt -keystore server-app.jks?
下面使用Spring Boot進行SSL雙向認證
程序結構如下:
關鍵代碼:
服務端
application.properties
spring.application.name=server-appserver.port=9002 server.ssl.enabled=true server.ssl.client-auth=need server.ssl.key-store=classpath:server-app.jks server.ssl.key-store-password=server-app server.ssl.key-alias=server-app server.ssl.key-store-type=JKS server.ssl.key-store-provider=SUN server.ssl.trust-store=classpath:server-app.jks server.ssl.trust-store-password=server-app server.ssl.trust-store-type=JKSController.java
package cn.server;import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/server-app") public class Controller {@GetMapping("/data")public String getData(){System.out.println("Returning data from server-app data method");return "Hello from Server-App-data method";} }客戶端
application.properties
spring.application.name=client-appserver.port=9001 server.ssl.enabled=true server.ssl.client-auth=need server.ssl.key-store=classpath:client-app.jks server.ssl.key-store-password=client-app server.ssl.key-alias=client-app server.ssl.key-store-type=JKS server.ssl.key-store-provider=SUN server.ssl.trust-store=classpath:client-app.jks server.ssl.trust-store-password=client-app server.ssl.trust-store-type=JKSendpoint.server-app=https://localhost:9002/server-app/dataClientMain.java
package cn.client;import org.apache.http.client.HttpClient; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.HttpClients; import org.apache.http.ssl.SSLContextBuilder; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.core.io.ClassPathResource; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.web.client.RestTemplate;import java.io.InputStream; import java.net.URI; import java.security.KeyStore;@SpringBootApplication public class ClientMain implements CommandLineRunner {@AutowiredRestTemplate restTemplate;@Value("${endpoint.server-app}")private String msEndpoint;@Beanpublic RestTemplate getRestTemplate(){RestTemplate restTemplate = new RestTemplate();KeyStore keyStore;HttpComponentsClientHttpRequestFactory requestFactory = null;try {keyStore = KeyStore.getInstance("jks");ClassPathResource classPathResource = new ClassPathResource("client-app.jks");InputStream inputStream = classPathResource.getInputStream();keyStore.load(inputStream, "client-app".toCharArray());SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()).loadKeyMaterial(keyStore, "client-app".toCharArray()).build(),NoopHostnameVerifier.INSTANCE);HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).setMaxConnTotal(Integer.valueOf(5)).setMaxConnPerRoute(Integer.valueOf(5)).build();requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);requestFactory.setReadTimeout(Integer.valueOf(10000));requestFactory.setConnectTimeout(Integer.valueOf(10000));restTemplate.setRequestFactory(requestFactory);}catch (Exception exception) {System.out.println("Exception Occured while creating restTemplate "+exception);exception.printStackTrace();}return restTemplate;}public static void main(String[] args) {SpringApplication.run(ClientMain.class, args);}@Overridepublic void run(String... args) throws Exception {String forObject = restTemplate.getForObject(new URI(msEndpoint), String.class);System.out.println(forObject);} }源碼打包下載地址:
https://github.com/fengfanchen/Java/tree/master/SpringBoot-two-way-ssl
總結
以上是生活随笔為你收集整理的Spring Boot文档阅读笔记-how-to-implement-2-way-ssl-using-spring-boot的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL工作笔记-达梦7中存储过程相关笔记
- 下一篇: Spring Boot笔记-设置拦截器为