Rest接口加Https单向认证
背景:
接到一个需求,客户要求某个模块的rest接口都得通过https访问,客户提供证书。
步骤:
Server端证书生成
刚开始还没拿到客户的证书,所以通过jdk自带的keytools自己先生成了一个证书用来测试,同事称这个为自签名。
C:\Program Files\Java\jdk1.8.0_191\jre\bin\keytool.exe 也就是jdk这个自带的程序, 说说怎么用吧。楼主用的windows操作系统
到JDK的JRE的bin目录下,执行以下命令生成服务端sslServer.p12文件
keytool -genkey -v -alias sslServer -keyalg RSA -storetype PKCS12 -keystore F:\httpsDemo\sslServer.p12
注意这个-alias很重要,是证书的别名,后面用得到。sslServer.p12就是生成的自签名证书了,后面需要用客户的证书替换。

看了一些博客的介绍,这个名字和姓氏得是主机的ip,不然会有问题,本着不踩坑的思想,照做就行。当然这里的密码是肯定要记住的。。
Spring配置
将sslServer.p12放在resource目录下,与application.properties同级
# 单向认证开启(客户端校验服务端证书即可)
server.ssl.key-store=classpath:sslServer.p12
server.ssl.key-store-password=server
server.ssl.key-alias=sslServer
server.ssl.keyStoreType=JKS
其中,server.ssl.key-store,server.ssl.key-store-password,server.ssl.key-alias需要根据客户提供的证书进行配置,
server.ssl.key-store对应证书位置,目前是用自生成的签名,部署时需要替换客户证书
server.ssl.key-store-password对应证书密码
server.ssl.key-alias对应生成证书时的证书别名
keyStoreType固定为JKS
到这里为止,服务端做https的认证就已经结束了,很简单吧。可以使用postman测试一波,记得关掉setting里的ssl认证,设置成off


客户端怎么认证
由于楼主的项目是微服架构,本身也会调到这个应用的服务,因此所有调到的地方都得特殊处理下。
https认证分两种,本文只介绍单向认证,即客户端无条件信任服务端的证书,因为我的需求就只要单向
RestTemplate配置
@Configuration
public class RestTemplateConfiguration {
@Value("${readTimeout}")
private String readTimeout;
@Value("${connectionTimeout}")
private String connectionTimeout;
@Bean("restTemplate")
public RestTemplate createRestTemplate() {
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule simpleModule = new SimpleModule();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
objectMapper.setDateFormat(dateFormat);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(simpleClientHttpRequestFactory());
List<HttpMessageConverter<?>> converters = new ArrayList<>();
MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
jsonConverter.setObjectMapper(objectMapper);
converters.add(jsonConverter);
restTemplate.setMessageConverters(converters);
return restTemplate;
}
private ClientHttpRequestFactory simpleClientHttpRequestFactory() {
SslClientHttpRequestFactory factory = new SslClientHttpRequestFactory();
factory.setConnectTimeout(Integer.parseInt(connectionTimeout));
factory.setReadTimeout(Integer.parseInt(readTimeout));
return factory;
}
自定义http请求类
public class SslClientHttpRequestFactory extends SimpleClientHttpRequestFactory {
/**
* 区分https请求
* @param connection
* @param httpMethod
* @throws IOException
*/
@Override
protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
if (connection instanceof HttpsURLConnection) {
prepareHttpsConnection((HttpsURLConnection) connection);
}
super.prepareConnection(connection, httpMethod);
}
private void prepareHttpsConnection(HttpsURLConnection connection) {
connection.setHostnameVerifier(new SkipHostnameVerifier());
try {
connection.setSSLSocketFactory(createSslSocketFactory());
}
catch (Exception ex) {
// Ignore
}
}
private SSLSocketFactory createSslSocketFactory() throws Exception {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, new TrustManager[]{new SkipX509TrustManager()}, new SecureRandom());
return context.getSocketFactory();
}
/**
* 忽略hostName校验,允许ip代替域名
*/
private static class SkipHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}
/**
* 信任所有证书
*/
private static class SkipX509TrustManager implements X509TrustManager {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
}
}
然后统一用这个restTemplate去调那个模块的https的服务就ok了,restTemplate怎么调不介绍,基本操作。
.crt和.key导成.p12格式的证书
你以为开发完了?没这么简单。
上面说到我们的证书使用的是自签名证书,但客户提供的证书可能并不是你想的.p12格式的,可能是一个.crt格式的证书加上一个.key格式的私钥。
这时候需要将.crt和.key导成.p12格式的证书。这里就要用到openssl工具了,怎么下载安装不介绍。
执行以下openssl指令导出.p12格式的证书
openssl pkcs12 -export -in test.crt -inkey test.key -passin pass:123456 -password pass:123456 -name server -out server.p12
其中test.crt为客户提供的crt证书
test.key 为客户提供的私钥文件
-passin pass:123456代表给私钥设置密码123456
-password pass:123456 代表给p12文件设置密码123456
-name server 代表导出的证书别名为server
server.p12 为导出的证书文件
则对应的服务器端配置如下
server.ssl.enabled=true
server.ssl.key-store=classpath:server.p12
server.ssl.key-store-password=123456
server.ssl.key-alias=server
server.ssl.key-store-type=JKS
https服务端和客户端的单向认证到此为止。
Rest接口加Https单向认证的更多相关文章
- java https单向认证(忽略认证)并支持http基本认证
https单向认证(忽略认证)并支持http基本认证, 温馨提示 1,jar包要导入对 2,有匿名类编译要注意 3,欢迎提问,拿走不谢!背景知识 Https访问的相关知识中,主要分为单向验证和双向验证 ...
- Tomcat添加HTTPS单向认证和双向认证
前言 前一段时间有了解如何配置Tomcat服务为Https单向认证和双向认证,当时也做了一些记录,今天开始写博客,就把以前的记录拿出来整理下,分享给大家.本文没有介绍证书如何生成,会在下一篇博文里介绍 ...
- java实现HTTPS单向认证&TLS指定加密套件
1.HTTPS介绍 由于HTTP是明文传输,会造成安全隐患,所以在一些特定场景中,必须使用HTTPS协议,简单来说HTTPS=HTTP+SSL/TLS.服务端和客户端的信息传输都是通过TLS进行加密. ...
- tomcat 配置https (单向认证)
1.单向认证,就是传输的数据加密过了,但是不会校验客户端的来源 2.双向认证,如果客户端浏览器没有导入客户端证书,是访问不了web系统的,找不到地址 如果只是加密,单向就行 如果想要用系统的人没有证书 ...
- https单向认证和双向认证区别
关于证书 1.每个人都可以使用一些证书生成工具为自己的站点生成证书(比如jdk的keytool),大家称它为“自签名证书”,但是自己生成的证书是不被互联网承认的,所以浏览器会报安全提示,要求你手动安装 ...
- Https单向认证和双向认证介绍
一.Http HyperText Transfer Protocol,超文本传输协议,是互联网上使用最广泛的一种协议,所有WWW文件必须遵循的标准.HTTP协议传输的数据都是未加密的,也就是明文的,因 ...
- 图解 https 单向认证和双向认证!
来源: 一.Http HyperText Transfer Protocol,超文本传输协议,是互联网上使用最广泛的一种协议,所有WWW文件必须遵循的标准.HTTP协议传输的数据都是未加密的,也就是明 ...
- https单向认证和双向认证
单向认证: .clinet<--server .clinet-->server .client从server处拿到server的证书,通过公司的CA去验证该证书,以确认server是真实的 ...
- https 单向认证和双向认证配置
HTTPS 是我们开发中经常用到的通信加密技术,能有效保护我们网络访问中的安全,本文主要讲解单向 和 双向 https 的配置.关于https 的实现原理在这里我就不赘述了,附上阮一峰老师的关于htt ...
随机推荐
- React学习路径快速进入AntDesignPro开发
好久没有写博客,有空再来记一下.最近在整些小东西,需要用到前端,最开始本着对nodejs的动不动几百兆插件的恐惧, 于是使用自己以前写的 OSS.Pjax 小框架(类似国外的Pjax,利用pushSt ...
- 诊断Java线程死锁
比如我们有运行这样一个程序: 了解多线程的小伙版都知道,这段代码不会有打印结果,因为发生了死锁.我们在服务器上运行试试,没有输出,对应的进程是 32752. 使用 “jstack 32752”排查,后 ...
- Spring-Validation(数据校验) 你值得拥有
前言 最近看到很多童鞋在项目中的对请求参数的校验都用的if来判断各参数的属性,如: if(StringUtils.isBlank(username)){ return RR.exception(&qu ...
- day04总结
print("陈少最帅!!!") 输出结果: 陈少最帅!!! 可以变,不可变数据类型#1.可变类型:list,dict#在值改变的情况下,id号不变,也就是说内存地址不变,证明就是 ...
- day14 参数
目录 一.参数介绍 二.形参与实参的具体使用 2.1位置参数 2.2关键字参数 2.3关键字实参和位置实参混合使用时 2.4默认参数 2.5位置形参和默认形参混用 2.6 可变长度的参数(*与**用法 ...
- nginx中的root和alias辨析
root介绍 Syntax: root path; Default: root html; Context: http, server, location, if in location Sets t ...
- 前端01 /HTML简单简绍
前端01 /HTML简单简绍 目录 前端01 /HTML简单简绍 1.web服务本质 2.浏览器的工作流程 3.HTML是什么 4.web服务本质 5.HTML文档结构 6.HTML注释 6.标签语法 ...
- 创建MongoDB副本集教程
今天有时间搞了一下mongoDB的副本集,遇到好多坑,写下此文,方便日后查阅! 本教程是在windows环境下安装测试的(我是本机一台 + 两台虚拟机) 本机:10.53.8.159 虚拟机一:10. ...
- 解决android studio Gradle无法同步问题
打开根目录build.gradle buildscript { repositories { // 添加阿里云 maven 地址 maven { url 'http://maven.aliyun.co ...
- .Net Core 常见错误解决记录
Error: String or binary data would be truncated. The statement has been terminated 数据库出错原因: 表字段创建的太短 ...