我是靠谱客的博主 现代手套,这篇文章主要介绍java进行https请求以及相关证书的生成,现在分享给大家,希望可以做个参考。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
最近在对接银联的支付业务,由于银联进行的https请求,把https的原理和java中如何使用进行了一个总结,希望对后面进行https请求的开发有所帮助. 首先需要了解https的原理,是一种基于SSL/TLS的Http,所有的http数据都是在SSL/TLS协议封装之上传输的。Https协议在Http协议的基础上,添加了SSL/TLS握手以及数据加密传输,也属于应用层协议。所以,研究Https协议原理,最终其实是研究SSL/TLS协议。具体了解SSL/TLS可以参照文档:http://www.fenesky.com/blog/2014/07/19/how-https-works.html。 SSL/TLS也是双方需要通过握手来验证请求双方都是安全的,为了验证双方的合法性,就需要交换双方的公钥证书,其实原理有点像非对称加密,所以首先你需要提供给银联一个公钥证书,银联也会提供一个公钥证书给你,但是java里面需要用keystore来保存公钥和私钥,下面是具体的步骤: 1.用工具keytool来生成本地的keystore: keytool -genkey -alias wjx -keypass wjx -keyalg RSA -keysize 1024 -validity 36500 -keystore e:/wjx.keystore -storepass 12345678 -keypass 123456789 -dname "CN=www.wjx.cn, OU=wjx, O=wjx, L=cq, ST=cq, C=cn" 其中: -storepass为指定密钥库的密码(获取keystore信息所需的密码) -keypass为指定别名条目的密码(私钥的密码) 但是可能银联会直接给你提供私钥和公钥的密钥对,而不是你生成(这个有点坑),这个时候就需要用公钥和私钥来生成keystore,具体步骤为: a.用公钥和私钥生成p12证书: openssl pkcs12 -export -in client.crt -inkey client.key -out client.p12 -name wjx -CAfile ca.crt -caname wjx 会要求你输入私钥的密码,和p12文件的密码1234567890(后面生成keystore的时候会用到) 其中client.key为私钥,client.crt为公钥,client.p12生成的p12格式的证书 b.再用p12文件生成对应的keystore(wjx.keystore): keytool -importkeystore -srckeystore client.p12 -srcstoretype pkcs12 -destkeystore e:/wjx.keystore -deststoretype jks -srcstorepass 1234567890 其中1234567890是keystore的密码 2.如果需要和银联交换公钥,就需要将本地生成的keystore导出公钥证书: keytool -export -alias wjx -keystore e:/wjx.keystore -file e:/wjx.crt -storepass 12345678 3.然后需要和他们交换公钥证书,他会给你提供公钥证书ca.crt; 4.生成的公钥证书需要转换为keystore才能java中使用,具体命令为: keytool -import -alias unionpay_https -keystore e:/unionpay_https.keystore -file ca.crt 生成好keystore过后就需要和银联进行握手的操作(主要是用KeyManagerFactory来管理自己的秘钥,TrustManagerFactory来管理对方的公钥证书):
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package Pay; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ConnectTimeoutException; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import javax.net.ssl.*; import java.io.FileInputStream; import java.net.SocketTimeoutException; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; /** * @author wangjianxing * @date 2016/1/4 15:21 */ public class HttpsSignUtil { public static final String DEFAULT_CHARSET = "UTF-8"; //设置默认通信报文编码为UTF-8 private static final int DEFAULT_CONNECTION_TIMEOUT = 1000 * 2; //设置默认连接超时为2s private static final int DEFAULT_SO_TIMEOUT = 1000 * 60; //设置默认读取超时为60s public static String postWithSign(String reqURL, String reqData ,String charset){ String respData = ""; HttpClient httpClient = new DefaultHttpClient(); httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, DEFAULT_CONNECTION_TIMEOUT); httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, DEFAULT_SO_TIMEOUT); try { KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); KeyStore trustKeyStore = KeyStore.getInstance(KeyStore.getDefaultType()); FileInputStream inputStream = new FileInputStream("E:\wjx.keystore");//加载自己的keystore FileInputStream trustInputStream = new FileInputStream("E:\ca.keystore");//加载银联提供的keystore try { keyStore.load(inputStream, "123456789".toCharArray());//123456789为生成keystore时的密码storepass trustKeyStore.load(trustInputStream, "1234567890".toCharArray());//1234567890为生成keystore时的密码storepass } catch (CertificateException e) { e.printStackTrace(); inputStream.close(); throw new CertificateException(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); inputStream.close(); throw new NoSuchAlgorithmException(); } TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509"); tmf.init(trustKeyStore); keyManagerFactory.init(keyStore, "123456789".toCharArray()); // 123456789为keypass为指定别名条目的密码(私钥的密码) TrustManager tms [] = tmf.getTrustManagers(); KeyManager keyManagers [] = keyManagerFactory.getKeyManagers(); SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(keyManagers, tms, new SecureRandom()); SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, new String[]{"TLSv1"}, null, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);//如果这个不写ALLOW_ALL_HOSTNAME_VERIFIER 就证书中的CN对应域名必须和请求的https地址一样 httpClient = HttpClients.custom() .setSSLSocketFactory(sslsf) .build(); HttpPost httpPost = new HttpPost(reqURL); httpPost.setHeader(HTTP.CONTENT_TYPE, "text/xml; charset=" + DEFAULT_CHARSET); httpPost.setEntity(new StringEntity(null==reqData?"":reqData, DEFAULT_CHARSET)); HttpResponse response = httpClient.execute(httpPost); HttpEntity entity = response.getEntity(); if(null != entity){ respData = EntityUtils.toString(entity, charset); } return respData; }catch(ConnectTimeoutException cte){ throw new RuntimeException("请求通信[" + reqURL + "]时连接超时", cte); }catch(SocketTimeoutException ste){ throw new RuntimeException("请求通信[" + reqURL + "]时读取超时", ste); }catch(Exception e){ throw new RuntimeException("请求通信[" + reqURL + "]时遇到异常", e); }finally{ httpClient.getConnectionManager().shutdown(); } } }

最后

以上就是现代手套最近收集整理的关于java进行https请求以及相关证书的生成的全部内容,更多相关java进行https请求以及相关证书内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(85)

评论列表共有 0 条评论

立即
投稿
返回
顶部