网络编程六:https请求(双向验证)
2016-12-23 11:47
393 查看
以微信支付退款api为例,写https的请求(微信支付v3的退款和撤销订单api都需要双向验证,刚好满足这个文章的需求)
步骤:
1、获取ca证书
2、生成jks版本的证书,并且,把格式为pem的ca证书导入
3、为SSLContext添加jks证书和cert证书
4、把需要传的数据填入PrintWriter里面
5、然后根据url发起请求
6、接收服务器返回回来的数据
HttpsPost.java(没有用任何第三方的jar)
就这样了,可以当做模板用,赞
步骤:
1、获取ca证书
2、生成jks版本的证书,并且,把格式为pem的ca证书导入
3、为SSLContext添加jks证书和cert证书
4、把需要传的数据填入PrintWriter里面
5、然后根据url发起请求
6、接收服务器返回回来的数据
HttpsPost.java(没有用任何第三方的jar)
import java.io.*; import java.net.URL; import java.security.*; import javax.net.ssl.*; public class HttpsPost { public static void main(String[] args) throws Exception { String path = "F:\\WORK\\workspace\\WebContent\\WEB-INF\\classes\\com\\demo\\certificate\\"; String caName = path+"rootca.pem"; String certName = path+"apiclient_cert.p12"; String caPass = ""; String certPass = "apiclient_cert"; String urlstr = "https://apihk.mch.weixin.qq.com/secapi/pay/reverse"; String datas = "<xml><appid>wx2421b1c4370ec43b</appid><mch_id>10000100</mch_id><nonce_str>0b9f35f484df17a732e537c37708d1d0</nonce_str><out_refund_no></out_refund_no><out_trade_no>1415757673</out_trade_no><refund_id></refund_id><transaction_id></transaction_id><sign>66FFB727015F450D167EF38CCC549521</sign></xml>"; httprequestwithcacert(path,caName,caPass,certName,certPass,urlstr,datas); } private static final String JKS_CA_FILENAME = "server.jks"; private static final String JKS_CA_ALIAS = "server"; private static final String JKS_CA_PASSWORD = ""; /** * post 请求,带双证书验证 */ public static void httprequestwithcacert(String path, String caName, String caPass, String certName, String certPass, String urlstr, String datas) throws Exception{ //IOException,CertificateException, KeyStoreException, NoSuchAlgorithmException,UnrecoverableKeyException, KeyManagementException String capath = path + caName; //ca证书路径加名字 String certpath = path + certName; //cert证书路径加名字 String jkspath = path + JKS_CA_FILENAME; //ca转 4000 jks后的文件路径加名字 File caFile = new File(capath); //把pem格式的ca导入到jks jksmaker(jkspath,caFile); PrintWriter out = null; BufferedReader in = null; String result = ""; try { //这里加载的证书需要是jks格式的 TrustManager[] tms = getTrustManagers(jkspath, caPass); KeyManager[] kms = getKeyManagers(certpath, certPass); SSLContext sslContext = SSLContext.getInstance("SSL"); // 如果服务器不要求私钥证书,kms 可以不填 sslContext.init(kms, tms, new java.security.SecureRandom()); SSLSocketFactory ssf = sslContext.getSocketFactory(); // 服务链接 URL url = new URL(urlstr); HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(ssf); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0"); // content-type 按具体需要进行设置 conn.setRequestProperty("content-type", "application/json"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(datas); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader( conn.getInputStream(), "UTF-8")); String line; while ((line = in.readLine()) != null) { result += line; } System.out.println(result); } catch (Exception e) { e.printStackTrace(); } finally { try { in.close(); out.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 加载信任证书库 * * @param trustStore * @param trustStorePass * @return * @throws IOException */ private static TrustManager[] getTrustManagers(String trustStore, String trustStorePass) throws IOException { try { String alg = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory factory = TrustManagerFactory.getInstance(alg); InputStream fp = new FileInputStream(trustStore); KeyStore ks = KeyStore.getInstance("JKS"); ks.load(fp, trustStorePass.toCharArray()); fp.close(); factory.init(ks); TrustManager[] tms = factory.getTrustManagers(); System.out.println(tms); return tms; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } return null; } /** * 加载私钥证书 * * @param keyStore * @param keyStorePass * @return * @throws IOException */ private static KeyManager[] getKeyManagers(String keyStore, String keyStorePass) throws IOException { try { String alg = KeyManagerFactory.getDefaultAlgorithm(); KeyManagerFactory factory = KeyManagerFactory.getInstance(alg); InputStream fp = new FileInputStream(keyStore); KeyStore ks = KeyStore.getInstance("PKCS12"); ks.load(fp, keyStorePass.toCharArray()); fp.close(); factory.init(ks, keyStorePass.toCharArray()); KeyManager[] keyms = factory.getKeyManagers(); System.out.println(keyms); return keyms; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } catch (CertificateException e) { e.printStackTrace(); } catch (UnrecoverableKeyException e) { e.printStackTrace(); } return null; } /** * CA证书生成/导入jks * * @param jkspath * @param caFile */ public static void jksmaker(String jkspath,File caFile) throws Exception{ File jksCAFile = new File(jkspath); if (!jksCAFile.isFile()) { CertificateFactory cf = CertificateFactory.getInstance("X.509"); FileInputStream in = new FileInputStream(caFile); Certificate certificate = cf.generateCertificate(in); in.close(); X509Certificate cert = (X509Certificate) certificate; FileOutputStream out = new FileOutputStream(jksCAFile); // store jks file KeyStore ks = KeyStore.getInstance("JKS"); ks.load(null, null); ks.setCertificateEntry(JKS_CA_ALIAS, cert); // store keystore ks.store(out, (JKS_CA_PASSWORD==null?null:JKS_CA_PASSWORD.toCharArray())); out.close(); } } }
就这样了,可以当做模板用,赞
相关文章推荐
- HTTPS网络加密双向验证->使用AFNetworking封装
- eclipse中使用Jetty插件实现https请求与SSL双向验证
- xUtils3.x的网络请求封装和请求https之单向SSL验证
- https实现双向验证请求
- 网络安全之配置双向PPP协议身份验证
- VC++网络安全编程范例(1)--数字证书有效期验证
- C++网络编程 如何使用SOCKET 发送HTTP1.1 GET POST请求包
- Java+Https+Tomcat双向验证实例
- ios开发之网络编程(请求--响应)
- JSP网络编程-请求和响应-HttpServletRequest-HttpServletResponse-学习笔记
- java例程练习(网络编程[简单双向通信试验])
- ios 网络编程之同步,异步,请求队列
- JAVA高级视频 网络编程 05 服务器端接受客户端请求的代码
- java网络编程二:服务器处理多个用户请求的解决方案(返回多个用户输入的信息)
- java网络编程二:服务器处理多个用户请求的解决方案(返回多个用户输入的信息)
- VC++网络安全编程范例(1)--数字证书有效期验证
- C#网络编程---(2) 经过验证并调试后适合自身环境的客户端socket通信
- java网络编程二:服务器处理多个用户请求的解决方案(返回多个用户输入的信息)
- 关于httpclient 请求https (如何绕过证书验证)
- iOS网络编程之同步、异步、请求队列