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双向认证的更多相关文章

  1. JDK自带工具keytool生成ssl证书 和 HTTPS双向认证

    创建证书(第一步) keytool -genkey -alias "baidu" -keypass "123456" -keystore "D:/ba ...

  2. iOS 用自签名证书实现 HTTPS 请求的原理

    在16年的WWDC中,Apple已表示将从2017年1月1日起,所有新提交的App必须强制性应用HTTPS协议来进行网络请求.默认情况下非HTTPS的网络访问是禁止的并且不能再通过简单粗暴的向Info ...

  3. AFNetWorking3.0使用 自签名证书的https请求

    前几日,项目组出于安全角度的考虑,要求项目中的请求使用https请求,因为是企业内部使用的app,因此使用了自签名的证书,而自签名的证书是不受信任的,所以我们就需要自己来做证书的验证,包括服务器验证客 ...

  4. https双向认证訪问管理后台,採用USBKEY进行系统訪问的身份鉴别,KEY的证书长度大于128位,使用USBKEY登录

    近期项目需求,须要实现用USBKEY识别用户登录,採用https双向认证訪问管理后台管理界面,期间碰到过一些小问题,写出来给大家參考下. 1:前期准备工作 USBKEY 硬件:我买的是飞天诚信 epa ...

  5. iOS使用自签名证书实现HTTPS请求

    概述 在16年的WWDC中,Apple已表示将从2017年1月1日起,所有新提交的App必须强制性应用HTTPS协议来进行网络请求. 默认情况下非HTTPS的网络访问是禁止的并且不能再通过简单粗暴的向 ...

  6. 生成自签名证书-开启https

    1.生成CA证书 # 生成 CA 私钥 openssl genrsa -out ca.key 2048 # X.509 Certificate Signing Request (CSR) Manage ...

  7. tomcat使用自签名证书实现https加密访问

    部署好java环境和tomcat之后 执行以下语句 #生成证书,keytool是java工具命令,-genkey生成证书,-alias证书名称,-keyalg应该是指算法,-keystore是证书存储 ...

  8. Tomcat服务器配置https双向认证(使用keytool生成证书)

    一,HTTPS原理   1,HTTP.HTTPS.SSL.TLS介绍与相互关系 (1)HTTP:平时浏览网页时候使用的一种协议.HTTP协议传输的数据都是未加密的(明文),因此使用HTTP协议传输隐私 ...

  9. nginx 自签名证书 配置 https

    最近在研究nginx,整好遇到一个需求就是希望服务器与客户端之间传输内容是加密的,防止中间监听泄露信息,但是去证书服务商那边申请证书又不合算,因为访问服务器的都是内部人士,所以自己给自己颁发证书,忽略 ...

随机推荐

  1. Dao、Controller、Service三层的结构划分

     Java Web基础--Controller+Service +Dao三层的功能划分(摘取自网络)1. Controller/Service/DAO简介:      Controller是管理业务( ...

  2. gorm框架表名自动加s问题

    查看日志会发现表名自动加了s 在model实现以下方法即可解决 type UsUser struct { ID int64 `gorm:"column:id" db:"c ...

  3. psutil模块详解

    import psutil#1.系统性能信息模块psutilmem = psutil.virtual_memory()print(mem)#svmem(total=8442675200, availa ...

  4. Three.js实现脸书元宇宙3D动态Logo

    背景 Facebook 近期将其母公司改名为 Meta,宣布正式开始进军 元宇宙 领域.本文主要讲述通过 Three.js + Blender 技术栈,实现 Meta 公司炫酷的 3D 动态 Logo ...

  5. Typora常用操作

    Typora常用操作 目录 Typora常用操作 1. 标题 2.子标题 3. 区块 4.代码 5. 表格 6. 超链接 7.单选框 8.数学公式 9.流程图 10.生成目录 11.字体设置 12. ...

  6. win10让人愤怒的磁盘占用100%问题

    升级win10以后其他还好.但是系统经常响应非常非常慢,后来观察发现每次非常卡的时候我的磁盘占用就是100%的. 我是技嘉的B85主板. 1盘是128g的东芝SSD(GPT), 2盘是WD的3TB H ...

  7. 说下我费了几个钟头才搞定的myeclipse和tomcat问题

    配置myeclipse与tomcat的时候,我根本没有想到myeclipse已经集成了tomcat,根据我上篇文章可以找到所集成的tomcat的位置.于是,自己下了一个tomcat,也许是自作聪明吧, ...

  8. [atARC124F]Chance Meeting

    为了方便,不妨先将$n$和$m$都减小1,其意义即为移动的次数 注意到老鼠向下移动和猫向上移动对于第2个条件是等价的,对于第1个条件即要求都恰好移动$n$次,那么对应的方案数即为${2n\choose ...

  9. [hdu6316]Odd shops

    记$m=10$,即商品的种类 记$g(x)=1+\sum_{i=1}^{m}a_{i}x_{i}$,问题即求$f_{n}(x)=g^{n}(x)$非0项数(模2意义下) 注意到$f^{2}(x)\eq ...

  10. [atAGC029F]Construction of a tree

    构造一张二分图,左边是$n$个点,右边是$n-1$个集合,按照点属于集合连边 定义一组匹配的意义,即说明该点的父亲在该集合中选择 利用dinic求出二分图的最大匹配,若不为$n-1$则无解,否则考虑如 ...