如何使用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 ...
随机推荐
- Netty学习(六)-LengthFieldBasedFrameDecoder解码器
在TCP协议中我们知道当我们在接收消息时候,我们如何判断我们一次读取到的包就是整包消息呢,特别是对于使用了长连接和使用了非阻塞I/O的程序.上节我们也说了上层应用协议为了对消息进行区分一般采用4种方式 ...
- CSS3: perspective 3D属性
本文引自:http://blog.csdn.net/cddcj/article/details/52956540 perspective 属性指定了观察者与z=0平面的距离,使具有三维位置变换的元素产 ...
- 天气预报APP(1)
一个天气预报APP至少应该具备以下功能: *可以罗列出全国所有的省.市.县: *可以查看全国任意城市的天气信息: *可以自由的切换城市,去查看其他城市的天气: *提供手动更新以及后台自动更新天气的功能 ...
- 【0726 | Day 2】编程语言分类/主流编程语言介绍/网络的瓶颈效应
编程语言分类 机器语言 与硬件交互 优点:执行效率高 缺点:开发效率低 汇编语言 间接与硬件交互 优点(相较于机器语言):开发效率高 缺点(相较于机器语言):执行效率低 高级语言 简单化指令,让人人都 ...
- 【CodeForces - 1200C】Round Corridor (数论gcd)
Round Corridor Descriptions Amugae位于一个非常大的圆形走廊中.走廊由两个区域组成.内部区域等于nñ扇区,外部区域等于m米部门.在相同区域(内部或外部)的每对扇区之间 ...
- 关于JSP页面的静态包含和动态包含
JSP中有两种包含:静态包含:<%@include file="被包含页面"%> 和 动态包含:<jsp:include page="被包含页面&quo ...
- 基于ZooKeeper的三种分布式锁实现
[欢迎关注公众号:程序猿讲故事 (codestory),及时接收最新文章] 今天介绍基于ZooKeeper的分布式锁的简单实现,包括阻塞锁和非阻塞锁.同时增加了网上很少介绍的基于节点的非阻塞锁实现,主 ...
- ansible批量自动配置Juniper
一.需求 有几台新上线的Juniper,需要批量配置下syslog,ntp,snmp基础配置 二.拓扑 三.实施步骤 1.读取配置并输出作为初步核查 2.把配置载入网络其中一台网络设备中,并做一个sh ...
- 第一章 .NET基础-C#基础
一.1.1. 基础语法 一.1.1.1. 注释符 一.1.1.1.1. 注释符的作用 l 注释 l 解释 一.1.1.1.2. C#中的3中注释符 l 单行注释 // l 多上注释 /* 要注释的内容 ...
- 服务器小白的我,是如何将 node+mongodb 项目部署在服务器上并进行性能优化的
前言 本文讲解的是:做为前端开发人员,对服务器的了解还是小白的我,是如何一步步将 node+mongodb 项目部署在阿里云 centos 7.3 的服务器上,并进行性能优化,达到页面 1 秒内看到 ...