SpringBoot服务间使用自签名证书实现https双向认证
SpringBoot服务间使用自签名证书实现https双向认证
以服务server-one和server-two之间使用RestTemplate以https调用为例
一、生成密钥
需要生成server-one和server-two的客户端密钥和一个信任库密钥
1.生成TrustStore(信任库)
keytool -genkey -alias trustkeys -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore trustKeys.p12 -validity 36500

2.生成server-one客户端密钥
keytool -genkey -alias server-one -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore server-one.p12 -validity 36500
3.生成server-two客户端密钥
keytool -genkey -alias server-two -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore server-two.p12 -validity 36500
4.导出客户端公钥添加到信任库
4.1 导出server-one的公钥
keytool -keystore server-one.p12 -export -alias server-one -file server-one-publicKey.cer
4.2 导出server-two的公钥
keytool -keystore server-two.p12 -export -alias server-two -file server-two-publicKey.cer
5.添加客户端公钥到信任库
keytool -import -alias server-one -v -file server-one-publicKey.cer -keystore trustKeys.p12
keytool -import -alias server-two -v -file server-two-publicKey.cer -keystore trustKeys.p12
以上2、3、4和5步骤填写信息与1基本相同,不再重复截图展示
部分命令解释
genkey 表示要创建一个新的密钥。
alias 表示 keystore 的别名。
keyalg 表示使用的加密算法是 RSA ,一种非对称加密算法。
keysize 表示密钥的长度。
keystore 表示生成的密钥存放位置。
validity 表示密钥的有效时间,单位为天。
二、配置SpringBoot支持https
1、拷贝相应密钥到resources

2、客户端配置文件application.properties对应的配置项
# 开启ssl
server.ssl.enabled=true
server.ssl.client-auth=need
#server.ssl.protocol=TLS
server.ssl.key-store=classpath:ssl/server-one.p12
#server.ssl.key-password=123456
server.ssl.key-store-password=123456
server.ssl.key-store-type=PKCS12
server.ssl.keyAlias=server-one
server.ssl.trust-store=classpath:ice-ca/trustKeys.p12
server.ssl.trust-store-password=123456
server.ssl.trust-store-type=PKCS12
3、服务端配置文件application.properties对应的配置项
# 开启ssl
server.ssl.enabled=true
server.ssl.client-auth=need
#server.ssl.protocol=TLS
server.ssl.key-store=classpath:ssl/server-two.p12
#server.ssl.key-password=123456
server.ssl.key-store-password=123456
server.ssl.key-store-type=PKCS12
server.ssl.keyAlias=server-two
server.ssl.trust-store=classpath:ice-ca/trustKeys.p12
server.ssl.trust-store-password=123456
server.ssl.trust-store-type=PKCS12
4、pom.xml配置文件添加配置项如下
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>ssl/server-one.p12</include>
<include>ice-ca/trustKeys.p12</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
5、启动服务并验证https
浏览器访问:https://localhost:8970/platformdictionary/queryDeviceType

此时无法访问
单击server-one.p12或server-two.p12为浏览器安装证书
安装后再次访问

点击确定后即可访问到页面
6、配置RestTemplate
pom添加httpclient支持
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
设置RestTemplate支持https请求
package com.hollysys.smartfactory.icedata.config;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import javax.net.ssl.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.*;
import java.security.cert.CertificateException;
import java.time.Duration;
/**
* Created by chendy on 2021/12/18 15:47
*/
@Configuration
@Slf4j
public class RestTemplateConfig {
@Value("${server.ssl.key-store-type}")
String clientKeyType;
@Value("${server.ssl.key-store}")
String clientPath;
@Value("${server.ssl.key-store-password}")
String clientPass;
@Value("${server.ssl.trust-store-type}")
String trustKeyType;
@Value("${server.ssl.trust-store}")
String trustPath;
@Value("${server.ssl.trust-store-password}")
String trustPass;
@Bean
public RestTemplate restTemplate() {
RestTemplate restTemplate = null;
try {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
// 客户端证书类型
KeyStore clientStore = KeyStore.getInstance(clientKeyType);
// 加载客户端证书,即自己的私钥
InputStream keyStream = getClass().getClassLoader().getResourceAsStream(clientPath);
clientStore.load(keyStream, clientPass.toCharArray());
// 创建密钥管理工厂实例
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
// 初始化客户端密钥库
keyManagerFactory.init(clientStore, clientPass.toCharArray());
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
// 创建信任库管理工厂实例
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore trustStore = KeyStore.getInstance(trustKeyType);
InputStream trustStream = getClass().getClassLoader().getResourceAsStream(trustPath);
trustStore.load(trustStream, trustPass.toCharArray());
// 初始化信任库
trustManagerFactory.init(trustStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
// 建立TLS连接
SSLContext sslContext = SSLContext.getInstance("TLS");
// 初始化SSLContext
sslContext.init(keyManagers, trustManagers, new SecureRandom());
// INSTANCE 忽略域名检查
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
CloseableHttpClient httpclient = HttpClients
.custom()
.setSSLSocketFactory(sslConnectionSocketFactory)
.setSSLHostnameVerifier(new NoopHostnameVerifier())
.build();
requestFactory.setHttpClient(httpclient);
requestFactory.setConnectTimeout((int) Duration.ofSeconds(15).toMillis());
restTemplate = new RestTemplate(requestFactory);
} catch (KeyManagementException | FileNotFoundException | NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (KeyStoreException | CertificateException | UnrecoverableKeyException | IOException e) {
e.printStackTrace();
}
return restTemplate;
}
}
7、添加测试代码
server-one中的test添加代码
@Test
public void testHello(){
String url = "https://127.0.0.1:8970/platformdictionary/queryDeviceType";
ResponseEntity<String> forEntity = restTemplate.getForEntity(url, String.class);
System.out.println(forEntity.toString());
}
server-two中的controller添加代码
@RestController
public class ServerTwoController {
@RequestMapping("/get")
public String get() {
return "双向认证成功";
}
}
测试执行结果
<200,双向认证成功,[Content-Type:"text/plain;charset=UTF-8", Content-Length:"3", Date:"Fri, 21 May 2021 08:12:51 GMT", Keep-Alive:"timeout=60", Connection:"keep-alive"]>
SpringBoot服务间使用自签名证书实现https双向认证的更多相关文章
- JDK自带工具keytool生成ssl证书 和 HTTPS双向认证
创建证书(第一步) keytool -genkey -alias "baidu" -keypass "123456" -keystore "D:/ba ...
- iOS 用自签名证书实现 HTTPS 请求的原理
在16年的WWDC中,Apple已表示将从2017年1月1日起,所有新提交的App必须强制性应用HTTPS协议来进行网络请求.默认情况下非HTTPS的网络访问是禁止的并且不能再通过简单粗暴的向Info ...
- AFNetWorking3.0使用 自签名证书的https请求
前几日,项目组出于安全角度的考虑,要求项目中的请求使用https请求,因为是企业内部使用的app,因此使用了自签名的证书,而自签名的证书是不受信任的,所以我们就需要自己来做证书的验证,包括服务器验证客 ...
- https双向认证訪问管理后台,採用USBKEY进行系统訪问的身份鉴别,KEY的证书长度大于128位,使用USBKEY登录
近期项目需求,须要实现用USBKEY识别用户登录,採用https双向认证訪问管理后台管理界面,期间碰到过一些小问题,写出来给大家參考下. 1:前期准备工作 USBKEY 硬件:我买的是飞天诚信 epa ...
- iOS使用自签名证书实现HTTPS请求
概述 在16年的WWDC中,Apple已表示将从2017年1月1日起,所有新提交的App必须强制性应用HTTPS协议来进行网络请求. 默认情况下非HTTPS的网络访问是禁止的并且不能再通过简单粗暴的向 ...
- 生成自签名证书-开启https
1.生成CA证书 # 生成 CA 私钥 openssl genrsa -out ca.key 2048 # X.509 Certificate Signing Request (CSR) Manage ...
- tomcat使用自签名证书实现https加密访问
部署好java环境和tomcat之后 执行以下语句 #生成证书,keytool是java工具命令,-genkey生成证书,-alias证书名称,-keyalg应该是指算法,-keystore是证书存储 ...
- Tomcat服务器配置https双向认证(使用keytool生成证书)
一,HTTPS原理 1,HTTP.HTTPS.SSL.TLS介绍与相互关系 (1)HTTP:平时浏览网页时候使用的一种协议.HTTP协议传输的数据都是未加密的(明文),因此使用HTTP协议传输隐私 ...
- nginx 自签名证书 配置 https
最近在研究nginx,整好遇到一个需求就是希望服务器与客户端之间传输内容是加密的,防止中间监听泄露信息,但是去证书服务商那边申请证书又不合算,因为访问服务器的都是内部人士,所以自己给自己颁发证书,忽略 ...
随机推荐
- Spring Boot程序中@JsonIgnoreProperties与@JsonIgnore基本使用
问题由来: springboot项目中定义了很多类,我们在rest返回中直接返回或者在返回对象中使用这些类,spring已经使用jackson自动帮我们完成这些的to json.但是有时候自动转的js ...
- 为什么建议使用你 LocalDateTime ,而不是 Date?
在项目开发过程中经常遇到时间处理,但是你真的用对了吗,理解阿里巴巴开发手册中禁用static修饰SimpleDateFormat吗 通过阅读本篇文章你将了解到: 为什么需要LocalDate.Loca ...
- python递归三战:Sierpinski Triangle、Tower of Hanoi、Maze Exploring
本文已做成视频教程投稿b站(视频版相对文本版有一些改进),点击观看视频教程 本文主要通过三个实例来帮助大家理解递归(其展示动画已上传B站): 谢尔宾斯基三角形(Sierpinski Triangle) ...
- SpringCloud微服务实战——搭建企业级开发框架(十七):Sentinel+Nacos配置持久化
Sentinel Dashboard中添加的规则是存储在内存中的,我们的微服务或者Sentinel一重启规则就丢失了,现在我们将Sentinel规则持久化配置到Nacos中,在Nacos中添加规则 ...
- GIS应用|快速开发REST空间分析服务
随着计算机的快速发展,GIS已经在各大领域得到应用,和我们的生活息息相关, 但是基于GIS几大厂商搭建服务,都会有一定的门槛,尤其是需要server,成本高,难度大,这里介绍一种在线GIS云平台,帮你 ...
- GeoServer style 配置样例
<?xml version="1.0" encoding="UTF-8"?> <StyledLayerDescriptor version=& ...
- ICCV2021 | PnP-DETR:用Transformer进行高效的视觉分析
前言 DETR首创了使用transformer解决视觉任务的方法,它直接将图像特征图转化为目标检测结果.尽管很有效,但由于在某些区域(如背景)上进行冗余计算,输入完整的feature maps ...
- Ubuntu文件权限管理
1.介绍 第一个是设备文件类型 以c开头的是字符 以b开头的是块存储 ls-l: 读写可执行 rwx | rwx | rwx 这个文件所属的用用户 组内其他成员 其他不属于用户组的成员 2.文件权限修 ...
- 【python】python之list
1.判断list是否为空 方式一: list_temp=[] if len(list_temp): #非空即为真 print('list is not empty') else: print('lis ...
- 【宏组学】如何根据taxid(或taxname)快速获得taxname(或taxid)?
需求 我有一个物种taxonomy ID的list,想获得相应的物种名,不要一个个去NCBI Taxonomy官网查.反之根据物种名list查询对应的taxid. 实现 因为之前没怎么用过,我的第一个 ...