如何使用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 ...
随机推荐
- [Apache Pulsar] 企业级分布式消息系统-Pulsar快速上手
Pulsar快速上手 前言 如果你还不了解Pulsar消息系统,可以先看上一篇文章 企业级分布式消息系统-Pulsar入门基础 Pulsar客户端支持多个语言,包括Java,Go,Pytho和C++, ...
- Linux下安装jupyter
又是美好的一天 开开心心写代码 1. 安装ipython, jupyter pip install ipython pip install jupyter 2. 生成配置文件[root@50e ...
- Python3源代码编译安装
Python3源代码编译安装 安装必要工具 yum-utils ,它的功能是管理repository及扩展包的工具 (主要是针对repository) $ sudo yum install yum-u ...
- Java 通过反射改变私有变量的值
直接上代码 import java.lang.reflect.Field; public class Main { public static void main(String[] args ...
- golang学习(1)---快速hello world
很多著名的计算机语言都是一两个人在业余时间捣鼓出来的,但是Go语言是由Google的团队打造的.可能一些基础的知识点我不会细讲,因为这个时代你真的得快速学习,才能适应发展. 来看看go的hello, ...
- (十一)c#Winform自定义控件-列表
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- 暂停研发surging,是否继续维护!
前言 surging从2017 年开始,2 年来利用业余时间为 surging语言添砖加瓦. 这种活雷锋行为并没有得到开发者们的理解,很多人甚至用命令的口吻,灵魂拷问方式要求活雷锋们再苦再累也得免费为 ...
- unsqueeze 和 squeeze
squeeze压缩的意思 就是在第几维为1 去掉 unsqueeze 解缩 在第几维增加 变成*1 squeeze用法 c = b.view(1, 1, 1, 2, 3) c.squeeze(0) # ...
- Python-PostgreSQL的使用
一.安装PostgreSQL模块 yum install postgresql-devel pip3 install psycopg2 注意:安装时遇到./psycopg/psycopg.h:35:2 ...
- 集合系列 List(二):ArrayList
ArrayList 是 List 集合的列表经典实现,其底层采用定长数组实现,可以根据集合大小进行自动扩容. public class ArrayList<E> extends Abstr ...