Java 通过证书访问Https服务
前言
有些HTTP 服务要求客户端在请求的时候使用证书加密/解密/授权 (客户端证书授权)。比如说下面的 curl 命令
curl --insecure \--cert cert.crt \ --key key.key \-d '{"name":"joel"}' \-H "Content-Type: application/json" \-X POST https://localhost:13321/get_user_info
那么,在Java中如何实现呢?
搜索关键词
- Java HTTPS client certificate authentication
- PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
- Certificate for <xxx.xxx.xxx.xxx> doesn’t match any of the subject alternative names: [xxx.xxx]
- Chia RPC Java
证书转换
将 crt 和 key 导出为 p12
openssl pkcs12 -export -in cert.crt -inkey key.key -out cert.p12 -name "joelzho.com"
备注:
- 将输出的密码记住
-name
的值最好是访问该服务接口的域名
示例代码
示例代码环境
<dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId><version>4.5.12</version>
</dependency>
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.TrustAllStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.SSLContexts;
import org.junit.Test;import javax.net.ssl.SSLContext;
import java.io.FileInputStream;
import java.security.KeyStore;/*** @author Joel*/
public class TestClientCertAuthHtttp {@Testpublic void test() throws Exception {final String certFile = "/path/to/cert.p12";final String storePass = "store-pass";final String keyPass = "key-pass";KeyStore keyStore;try (FileInputStream fis = new FileInputStream(certFile)) {keyStore = KeyStore.getInstance("PKCS12"); // or "JKS"keyStore.load(fis, storePass.toCharArray());}SSLContextBuilder sslContextBuilder = SSLContexts.custom();sslContextBuilder.loadTrustMaterial(TrustAllStrategy.INSTANCE);sslContextBuilder.loadKeyMaterial(keyStore, keyPass.toCharArray());SSLContext sslContext = sslContextBuilder.build();HttpClientBuilder httpClientBuilder = HttpClients.custom();httpClientBuilder.setSSLContext(sslContext);httpClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);CloseableHttpClient httpClient = httpClientBuilder.build();// ....}
}
代码解读
密码
p12 (PKCS12) 证书只有一个密码,即 storePass
和 keyPass
相等.
如果是 jks 证书的话,两个密码大概率不同(看你导出jks证书的时候怎么设置的)
loadTrustMaterial
sslContextBuilder.loadTrustMaterial(TrustAllStrategy.INSTANCE);
这句代码主要是用来解决自签名证书不被Java信任的问题。相关的类有
- TrustStrategy: 一个接口
- TrustAllStrategy: 信任所有
- TrustSelfSignedStrategy: 信任自签名证书
这里选择 TrustAllStrategy
的原因是 TrustSelfSignedStrategy
的实现在开发环境可能无效(比如说不小心将证书导入到系统中了,然后你代码中又指定了一遍,详情看该类的实现代码)。
当然,最安全的做法是自己实现 TrustStrategy
在里面写验证。
相关异常:PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
setSSLHostnameVerifier
httpClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
这句代码主要是用来忽略证书里面的 host
和 实际请求的 host
不一致验证。
也许证书颁发机构给的证书里面写定的是一个域名,但是你本机做测试的时候没有域名或这个证书被用在不同的服务里面。那么加上这个句代码即可。
相关异常:Certificate for <xxx.xxx.xxx.xxx> doesn’t match any of the subject alternative names: [xxx.xxx]
番外
jks 证书怎么导出?
在这个示例中,你要先有一个 p12 格式的证书 (见上文)
keytool -importkeystore \-deststorepass storepassword \-destkeypass keypassword \-destkeystore cert.jks \-srckeystore cert.p12 \-srcstoretype PKCS12 \-srcstorepass srcstorepass \-alias joelzho.com
备注:
deststorepass
和destkeypass
的值要用到代码中srcstorepass
是 p12证书的密码-alias
的值最好是访问该服务接口的域名- 获取 KeyStore实例的代码修改为:
KeyStore.getInstance("JKS");
参考链接
- Java HTTPS client certificate authentication
- Java equivalent of a rest call using curl command line utility to a https url with certs
- Use Java commons-httpclient with cacert, cert and key extracted from .pfx
- Class AllowAllHostnameVerifier
Java 通过证书访问Https服务相关推荐
- 如何制作SSL证书即https服务支持
如何制作SSL证书即https服务支持 目的 最近需要做个网站,支持https的访问,但是,是内部使用的,不需要对外网开放. 基础知识 在制作之前先了解一下OpenSSL.HTTPS的关系.见http ...
- Spring Boot RestTemplate 忽略证书访问https
在Spring Boot中,RestTemplate 一般使用 @Autowired 注解自动装配, 类似: @Autowiredprivate RestTemplate restTemplate; ...
- curl+个人证书访问https站点
目前,大公司的OA管理系统(俗称内网),安全性要求较高,通常采用https的双向 认证模式. 首先,什么是https,简单的说就是在SSL协议之上实现的http协议(get.post等操作) 什么是双 ...
- Java生成证书用HTTPS进行访问
文章目录 一.CA证书是什么? 1. 什么是CA? 2. 什么是证书? 3. 证书生成过程 4. 将数字签名房价到数字证书上,变成一个签过名的数字证书 二.Java生成证书 1.进入JDK的bin目录 ...
- HttpClient 使用证书访问https站点
使用HttpClient访问https 站点时,如果JRE或者JDK没有导入某个站点的证书,则会报如下错误: javax.net.ssl.SSLHandshakeException: sun.secu ...
- 国产化之银河麒麟.netcore3.1访问https服务的两个问题
背景 某个项目需要实现基础软件全部国产化,其中操作系统指定银河麒麟,数据库使用达梦V8,CPU平台的范围包括x64.龙芯.飞腾.鲲鹏等. 考虑到这些基础产品对.NETCore的支持,最终选择了3.1版 ...
- 无证书访问https外部接口
楼主公司需要调用gis服务器,但是服务器提供的https请求,同时公司也没有证书,这样会照成访问后不能直接调到接口,需要手动添加证书.所以用一下方式调用https接口可以避免上述情况. java直接访 ...
- CURL使用SSL证书访问HTTPS
在支付的交互过程中,安全绝对是需要考虑的重要因素之一.体现在对服务器交互数据的签名等环节,但有的时候为了能达到更高的安全级别,还需要用ssl证书,即web服务器有证书,浏览器客户端/请求端也需要安装证 ...
- curl 忽略证书访问 https
在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具.然而在使用cr ...
最新文章
- (0108)iOS开发之Xcode11: 删除默认Main.storyBoard、自定义根控制器
- A better way to learn D3 js - iLearning D3.js
- 多线程读取矩阵文件+多线程矩阵乘法(C++实现)
- python16_day37【爬虫2】
- Retrofit之CallAdapter简单解析
- cwm recovery 6.0.2.3下载_造梦西游3星辰辅助下载-造梦西游3星辰修改器下载v3.7.0 免费版...
- Spring Cloud Feign声明式服务调用 (学习总结)
- Mip-NeRF:抗混叠的多尺度神经辐射场ICCV2021
- 分布式数据库系统体系结构
- 扩展欧几里得算法(简单易懂,详细分析)
- PolyCluster: Minimum Fragment Disagreement Clustering for Polyploid Phasing 多聚类:用于多倍体的最小碎片不一致聚类...
- 头条小程序登录40014 bad params
- mysql查缺补漏(一) and or优先级和多表join
- QT-学生信息管理系统
- 中国哪里的大米最好吃?这几个地区最出名,网友为此吵翻了
- 行车路线(改)(图的应用)
- IOS学习六:Date Picker, Picker View选取器控件初步
- Mac: 账户失去了管理员权限,怎么办?!网上流行的和没见过的都在这里。
- flutter 国际化flutter使用 intl插件,provider状态保存
- c语言第七八次作业,二级C语言第七八次讲义.doc
热门文章
- 就业关键_个人职业规划(1)--个人职业规划的意义
- 用python预测小孩的身高_python的cm_ycm python_python按公式预测身高 - 云+社区 - 腾讯云...
- 【学海无涯】Java成神之路
- EasyAR_遇到的各种问题
- 使用TCP RFC 1323进行Windows XP网络性能优化
- submit写C语言怎么运行,submit提交方法(一)
- ES服务器搭建以及常遇问题处理
- 使用Burpsuit简单的暴力破解pikachu
- 无线WiFi安全渗透与攻防(二)之打造专属字典
- jsp+servlet+mysql实现的高校科研管理系统源码+运行教程+包运行