如何使用Java访问双向认证的Https资源
本文的相关源码位于 https://github.com/dreamingodd/CA-generation-demo
0.Nginx配置Https双向认证
首先配置Https双向认证的服务器资源。
可以参考:http://www.cnblogs.com/dreamingodd/p/7357029.html
完成之后如下效果:

1.导入cacerts进行访问
首先将服务器证书导入keystore cacerts,默认密码为changeit,如果需要修改密码就改一下。
keytool -import -alias ssl.demo.com -keystore cacerts -file C:\Development\deployment\ssl\ca-demo\server.crt
需要使用管理员权限到你使用的JDK security目录下执行(注意如果你有多个JDK的情况),效果如下:

然后使用Java访问:
package me.dreamingodd.ca; import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.security.KeyStore; /**
* #1
* HTTPS 双向认证 - direct into cacerts
* @Author Ye_Wenda
* @Date 7/11/2017
*/
public class HttpsKeyStoreDemo {
// 客户端证书路径,用了本地绝对路径,需要修改
private final static String PFX_PATH = "C:\\Development\\deployment\\ssl\\ca-demo\\client.p12";
private final static String PFX_PWD = "demo"; //客户端证书密码及密钥库密码 public static String sslRequestGet(String url) throws Exception {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
InputStream instream = new FileInputStream(new File(PFX_PATH));
try {
// 这里就指的是KeyStore库的密码
keyStore.load(instream, PFX_PWD.toCharArray());
} finally {
instream.close();
} SSLContext sslcontext = SSLContexts.custom().loadKeyMaterial(keyStore, PFX_PWD.toCharArray()).build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslcontext
, new String[] { "TLSv1" } // supportedProtocols ,这里可以按需要设置
, null // supportedCipherSuites
, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
try {
HttpGet httpget = new HttpGet(url);
// httpost.addHeader("Connection", "keep-alive");// 设置一些heander等
CloseableHttpResponse response = httpclient.execute(httpget);
try {
HttpEntity entity = response.getEntity();
// 返回结果
String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8");
EntityUtils.consume(entity);
return jsonStr;
} finally {
response.close();
}
} finally {
httpclient.close();
}
} public static void main(String[] args) throws Exception {
System.out.println(sslRequestGet("https://ssl.demo.com/"));
} }
运行结果如下:

2.生成truststore库文件进行访问-原生方式
如果服务器的JDK/JRE不能随便改动,我们还可以使用生成truststore库的方式来实现。
首先通过ca.crt生成自己的truststore,把ca.crt复制一份,重命名为ca.cer,复制到security目录下,执行
keytool -keystore demo.truststore -keypass demodemo -storepass demodemo -alias DemoCA -import -trustcacerts -file ca.cer
效果如下:

使用生成的demo.truststore和client.p12进行java访问:
package me.dreamingodd.ca; import javax.net.ssl.*;
import java.io.*;
import java.net.URL;
import java.nio.charset.Charset;
import java.security.KeyStore; /**
* #2
* HTTPS 双向认证 - use truststore
* 原生方式
* @Author Ye_Wenda
* @Date 7/11/2017
*/
public class HttpsTruststoreNativeDemo {
// 客户端证书路径,用了本地绝对路径,需要修改
private final static String CLIENT_CERT_FILE = "C:/Development/deployment/ssl/ca-demo/client.p12";
// 客户端证书密码
private final static String CLIENT_PWD = "demo";
// 信任库路径
private final static String TRUST_STRORE_FILE = "C:\\Development\\deployment\\ssl\\ca-demo\\demo.truststore";
// 信任库密码
private final static String TRUST_STORE_PWD = "demodemo"; private static String readResponseBody(InputStream inputStream) throws IOException {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
StringBuffer sb = new StringBuffer();
String buff = null;
while((buff = br.readLine()) != null){
sb.append(buff+"\n");
}
return sb.toString();
} finally {
inputStream.close();
}
} public static void httpsCall() throws Exception {
// 初始化密钥库
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance("SunX509");
KeyStore keyStore = getKeyStore(CLIENT_CERT_FILE, CLIENT_PWD, "PKCS12");
keyManagerFactory.init(keyStore, CLIENT_PWD.toCharArray()); // 初始化信任库
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance("SunX509");
KeyStore trustkeyStore = getKeyStore(TRUST_STRORE_FILE, TRUST_STORE_PWD,"JKS");
trustManagerFactory.init(trustkeyStore); // 初始化SSL上下文
SSLContext ctx = SSLContext.getInstance("SSL");
ctx.init(keyManagerFactory.getKeyManagers(), trustManagerFactory
.getTrustManagers(), null);
SSLSocketFactory sf = ctx.getSocketFactory(); HttpsURLConnection.setDefaultSSLSocketFactory(sf);
String url = "https://ssl.demo.com";
URL urlObj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) urlObj.openConnection();
con.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36");
con.setRequestProperty("Accept-Language", "zh-CN;en-US,en;q=0.5");
con.setRequestMethod("GET"); String response = readResponseBody(con.getInputStream());
System.out.println(response);
} /**
* 获得KeyStore
*
* @param keyStorePath
* @param password
* @return * @throws Exception
*/
private static KeyStore getKeyStore(String keyStorePath, String password,String type)
throws Exception {
FileInputStream is = new FileInputStream(keyStorePath);
KeyStore ks = KeyStore.getInstance(type);
ks.load(is, password.toCharArray());
is.close();
return ks;
} public static void main(String[] args) throws Exception {
httpsCall();
} }
结果同1。
3.生成truststore库文件进行访问-Apache HTTP 组件方式
package me.dreamingodd.ca; import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients; import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import java.io.*;
import java.net.URI;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.security.SecureRandom; /**
* #3
* HTTPS 双向认证 - use truststore
* Apache插件
* @Author Ye_Wenda
* @Date 7/11/2017
*/
public class HttpsTruststoreApacheContextDemo {
// 客户端证书路径,用了本地绝对路径,需要修改
private final static String CLIENT_CERT_FILE = "C:/Development/deployment/ssl/ca-demo/client.p12";
// 客户端证书密码
private final static String CLIENT_PWD = "demo";
// 信任库路径
private final static String TRUST_STRORE_FILE = "C:\\Development\\deployment\\ssl\\ca-demo\\demo.truststore";
// 信任库密码
private final static String TRUST_STORE_PWD = "demodemo"; private static String readResponseBody(InputStream inputStream) throws IOException {
try{
BufferedReader br = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8")));
StringBuffer sb = new StringBuffer();
String buff = null;
while((buff = br.readLine()) != null){
sb.append(buff+"\n");
}
return sb.toString();
}finally{
inputStream.close();
}
} public static void httpsCall() throws Exception {
// 初始化密钥库
KeyManagerFactory keyManagerFactory = KeyManagerFactory
.getInstance("SunX509");
KeyStore keyStore = getKeyStore(CLIENT_CERT_FILE, CLIENT_PWD, "PKCS12");
keyManagerFactory.init(keyStore, CLIENT_PWD.toCharArray()); // 初始化信任库
TrustManagerFactory trustManagerFactory = TrustManagerFactory
.getInstance("SunX509");
KeyStore trustkeyStore = getKeyStore(TRUST_STRORE_FILE, TRUST_STORE_PWD,"JKS");
trustManagerFactory.init(trustkeyStore); // SSLContext sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, "123456".toCharArray())
// .loadTrustMaterial(new File(TRUST_STRORE_FILE),"012345".toCharArray()).setSecureRandom(new SecureRandom()).useProtocol("SSL").build();
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,new String[]{"TLSv1", "TLSv2", "TLSv3"},null,
SSLConnectionSocketFactory.getDefaultHostnameVerifier()); CloseableHttpClient closeableHttpClient = HttpClients.custom().setSSLContext(sslContext).build();
HttpGet getCall = new HttpGet();
getCall.setURI(new URI("https://ssl.demo.com"));
CloseableHttpResponse response = closeableHttpClient.execute(getCall);
System.out.println(convertStreamToString(response.getEntity().getContent())); } public static String convertStreamToString(InputStream is) {
/*
* To convert the InputStream to String we use the BufferedReader.readLine()
* method. We iterate until the BufferedReader return null which means
* there's no more data to read. Each line will appended to a StringBuilder
* and returned as String.
*/
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder(); String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
} return sb.toString();
} /**
* 获得KeyStore
*
* @param keyStorePath
* @param password
* @return
* @throws Exception
*/
private static KeyStore getKeyStore(String keyStorePath, String password,String type)
throws Exception {
FileInputStream is = new FileInputStream(keyStorePath);
KeyStore ks = KeyStore.getInstance(type);
ks.load(is, password.toCharArray());
is.close();
return ks;
} public static void main(String[] args) throws Exception {
httpsCall();
}
}
结果同2。
本文的相关源码位于 https://github.com/dreamingodd/CA-generation-demo
dreamingodd原创文章,如转载请注明出处。
如何使用Java访问双向认证的Https资源的更多相关文章
- 使用火狐浏览器访问双向认证的k8s api
首先 不能在火狐里对要访问的网址添加例外 打开 选项->高级->查看证书->证书机构->导入.先择服务端ca.crt后根据提示导入证书 生成p12文件 openssl pkcs ...
- java 访问 kerberos 认证的 kafka
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- Https、OpenSSL自建CA证书及签发证书、nginx单向认证、双向认证及使用Java访问
0.环境 本文的相关源码位于 https://github.com/dreamingodd/CA-generation-demo 必须安装nginx,必须安装openssl,(用apt-get upd ...
- ssl介绍以及双向认证和单向认证原理
SSL安全证书可以自己生成,也可以通过第三方的CA(Certification Authority)认证中心付费申请颁发. SSL安全证书包括: 1. CA证书,也叫根证书或中间级证书.单 ...
- SSL双向认证和SSL单向认证的流程和区别
refs: SSL双向认证和SSL单向认证的区别https://www.jianshu.com/p/fb5fe0165ef2 图解 https 单向认证和双向认证!https://cloud.tenc ...
- windows下tomcat+nginx+openssl配置双向认证
1. 基础知识 CA证书:https://blog.csdn.net/yangyuge1987/article/details/79209473 SSL双向认证原理:https://blog.csdn ...
- 基于java的https双向认证,android上亦可用
From: http://my.oschina.net/jjface/blog/339144 概述: 客户端,浏览器或者使用http协议和服务器通信的程序. 如: 客户端通过浏览器访问某一网站时,如果 ...
- phantomjs 双向认证,访问nginx,https
应用背景: phantomjs的一个爬虫,访问https站点,单向认证(只认证服务器身份)的都可以,双向认证(服务器和客户端都需要认证)必须上传本地证书: 开始用一个包含公钥私钥的PEM证书访问,怎么 ...
- https 单向认证和双向认证配置
HTTPS 是我们开发中经常用到的通信加密技术,能有效保护我们网络访问中的安全,本文主要讲解单向 和 双向 https 的配置.关于https 的实现原理在这里我就不赘述了,附上阮一峰老师的关于htt ...
随机推荐
- Scala函数式编程(三)
Scala既是一门面向对象(OOP)语言,又是一门函数式编程(FP)语言.作为一门支持函数式编程的语言,Scala鼓励面向表达式编程(EOP)模型.简单来说,EOP中每个语句都有返回值.这一模式很明显 ...
- java学习-NIO(五)NIO学习总结以及NIO新特性介绍
我们知道是NIO是在2002年引入到J2SE 1.4里的,很多Java开发者比如我还是不知道怎么充分利用NIO,更少的人知道在Java SE 7里引入了更新的输入/输出 API(NIO.2).但是对于 ...
- react-navigation报错
用react-navigation配置路由时,出现如下报错或白屏. 我的代码原来是 import {AppRegistry} from 'react-native'; import App from ...
- Hibernate的执行流程
Hibernate框架的工作流程 1.通过Configuration().configure();读取并解析hibernate.cfg.xml配置文件 2.由hibernate.cfg.xml中的&l ...
- 一个web前端开发者的日常唠叨
时间飞逝,距离上一次更新博客已经过去了三个月,上一篇博客的发布时间停留在了4月4日. 近来三个月没有更新博客,深感抱歉和愧疚.停更博客就意味着学习的越来越少,作为一个普通的前端开发者来说这是万万不可取 ...
- tk.mybatis扩展通用接口
一.tk.mybatis已经为我们封装好了许多拆箱即用的通用mapper,但在实际的项目开发中想必不少小伙伴在数据库设计中都会采用逻辑删除这种方案,再去使用通用的mapper接口就不行了.这时候就需要 ...
- (十七)c#Winform自定义控件-基类窗体
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- Flutter学习笔记(20)--FloatingActionButton、PopupMenuButton、SimpleDialog、AlertDialog、SnackBar
如需转载,请注明出处:Flutter学习笔记(20)--FloatingActionButton.PopupMenuButton.SimpleDialog.AlertDialog.SnackBar F ...
- linux环境下测试环境搭建
一.linux环境下测试环境搭建过程简述: 1.前端后台代码未分离情况下: 主要步骤为:安装jdk,安装mysql,安装tomcat,将项目代码部署到tomcat/webapps/下. 2.前端后台代 ...
- 2019-在iOS里添加admob横幅广告示例
下载sdk , 解压 导入项目文件夹: 在info.plist里加入应用id(不是广告单元id): GADApplicationIdentifier 设置Build Settings选项 设置ap ...