java调用HTTPS

 这两天在做与渠道联调的回调,其中回调渠道的时候使用的是https。

简单的测试代码如下;

 

public static void simpleTest(String httpsURL) throws Exception {
	URL myurl = new URL(httpsURL);
	HttpsURLConnection con = (HttpsURLConnection) myurl.openConnection();
	InputStream ins = con.getInputStream();
	InputStreamReader isr = new InputStreamReader(ins);
	BufferedReader in = new BufferedReader(isr);
	String inputLine;
	while ((inputLine = in.readLine()) != null) {
		System.out.println(inputLine);
	}
	in.close();
}

 

但是,如果为自签发的SSL证书(未提供证书发行链而不被信任)的请求地址,上面的代码就不起作用了。

错误为:

 Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target。

 

经过查找资料,现有两种解决方案:

1)为自身系统增加证书

 

2)绕过证书验证

 

先来说第一种方案:

1)用IE打开访问的https网址,点击地址栏后面的小锁头(或证书错误标识),查看证书。在弹出的证书信息框中选择第二个页签“详细信息”。点击复制到文件,选择Base64编码的X.509证书导出即可。

2)把证书从其它文件导入到TrustStore文件中。

keytool -import -file D:/test1.cer -keystore D:/crt_test1

执行命令后要求输入密码,记住输入的密码。

 

3)编写如下代码:

 

public static void certTest1()throws Exception{
		String httpsURL = "https://xxx.xxx.cn/";
		String trustStor="D:/crt_test1";
		System.setProperty("javax.net.ssl.trustStore", trustStor);
		URL myurl = new URL(httpsURL);
		HttpsURLConnection con = (HttpsURLConnection) myurl.openConnection();
		con.setHostnameVerifier(hv);
		InputStream ins = con.getInputStream();
		InputStreamReader isr = new InputStreamReader(ins);
		BufferedReader in = new BufferedReader(isr);
		String inputLine=null;
		while ((inputLine = in.readLine()) != null) {
			System.out.println(inputLine);
		}
		in.close();
}
private static HostnameVerifier hv = new HostnameVerifier() {
		public boolean verify(String urlHostName, SSLSession session) {
			return urlHostName.equals(session.getPeerHost());
		}
};

 可是如果出现两个https地址并且证书不同的话,上面的代码就没有办法处理了。有人可能说用System.setProperty重新设置一下trustStore,很抱歉,我试了好几次,没有成功。如果他人有成功的请给出代码,谢谢。

 

为了处理两个证书的情况,我又查了下资料,整理一下,使用TrustManager来处理(此时会用到证书的密码)。

代码如下:

public static void certTest2(String certDir, String passwd, String urlStr)
		throws Exception {
	SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
	TrustManager[] tms = getTms(certDir, passwd);
	sslContext.init(null, tms, new java.security.SecureRandom());
	SSLSocketFactory ssf = sslContext.getSocketFactory();

	URL url = new URL(urlStr);
	HttpsURLConnection.setDefaultHostnameVerifier(hv);
	HttpsURLConnection conn = ((HttpsURLConnection) url.openConnection());
	conn.setSSLSocketFactory(ssf);

	InputStreamReader im = new InputStreamReader(conn.getInputStream(),
	
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值