HttpClient 4.5 利用HTTPS提交POST请求

HttpClient 4.5 利用HTTPS提交POST请求

最近在写一个测试服务器的程序,其中需要使用HTTPS协议,向服务器提交多个请求,由于服务器的证书是自己做的,因此要做证书的验证等工作。在网上查了许多例子,发现都不太合适,因为大部分代码都没做证书验证,所以容易受到中间人攻击。这里查阅了许多文档,并编写了自己的代码,做一个总结。

我这里使用了HttpClient 4.5版本。

参考了Oracle的文档:http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html,SSL相关概念和协议内容在该文档中已经非常详细的介绍了,这里也不再赘述。

接下来直接上代码了。

首先需要实现一个X509TrustManager接口,这个接口是用来判断服务器提供的证书是否可以被客户端信任。这个类需要一个证书,我们可以通过浏览器的导出证书功能,将服务器上我们自己创建的证书导出在本地。在MyX509TrustManager的构造方法中,利用CertificateFactory生成一个Certificate实例。checkClientTrusted是用来检查客户端的证书的,这里我们只需要检测服务器端的证书就可以了,因此checkClientTrusted方法体就不添加代码了。checkServerTrusted是用来检查服务器端证书的合法性的,我们在这里对它进行一些处理。我这里用了一个非常简单的方法,就是比较服务器端发送来的证书和自己本地的证书是否一致。如果没有一样的证书,就直接抛出异常。

package com.uestc.test.upload; import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; import javax.net.ssl.X509TrustManager; public class MyX509TrustManager implements X509TrustManager { private Certificate cert = null; public MyX509TrustManager() { try { FileInputStream fis = new FileInputStream( "/Users/justyoung/Desktop/upload/Cloud3"); BufferedInputStream bis = new BufferedInputStream(fis); CertificateFactory cf = CertificateFactory.getInstance("X.509"); while (bis.available() > 0) { cert = cf.generateCertificate(bis); // System.out.println(cert.toString()); } bis.close(); } catch (CertificateException | IOException e) { e.printStackTrace(); } } @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { for (X509Certificate cert : chain) { if (cert.toString().equals(this.cert.toString())) return; } throw new CertificateException("certificate is illegal"); } @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[] { (X509Certificate) cert }; } }

然后,又实现了一个HostnameVerifier接口,这个类主要是在SSL握手时验证对方主机名称的,这样做的一个目的也是防止链接被重定向到其他的不安全的地址上去,并且若出现服务器证书上的Hostname和实际的URL不匹配时,也能做一些处理,否则会抛出这样的异常:javax.net.ssl.SSLPeerUnverifiedException: Host name ‘192.168.2.177’ does not match the certificate subject provided by the peer,因此实现HostnameVerifier接口,我们能做一些hostname确认的工作,提高安全性。

package com.uestc.test; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLSession; public class MyVerifyHostname implements HostnameVerifier { @Override public boolean verify(String arg0, SSLSession arg1) { if (arg0.equals("192.168.2.177") || arg0.equals("cyber-space2015.imwork.net")) return true; else return false; } }

最后就是利用HttpClient来完成Post请求的提交了。这里我们自定义了SSLContext,需要使用init方法,并传递进我们自己创建的TrustManager实例数组。然后利用HttpClients的custom方法自定义了一些参数,并生成HttpClient实例。其他代码就没什么特殊的了。

package com.uestc.test; import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.client.utils.URIBuilder; import org.apache.http.entity.BufferedHttpEntity; import org.apache.http.entity.FileEntity; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class UploadTest { private String host; private String cookie; private String path; private int port; private SSLContext sslContext; private X509TrustManager tm; private HttpClient httpClient; public UploadTest(String host, String cookie, String path, int port) throws Exception { this.host = host; this.cookie = cookie; this.path = path; this.port = port; sslContext = SSLContext.getInstance("TLS"); tm = new MyX509TrustManager(); sslContext.init(null, new TrustManager[] { tm }, new java.security.SecureRandom()); httpClient = HttpClients.custom() .setSSLHostnameVerifier(new MyVerifyHostname()) .setSSLContext(sslContext).build(); } public String uploadFile(String localPath, String filename) throws URISyntaxException, ClientProtocolException, IOException { URI uri = new URIBuilder().setScheme("https").setHost(host) .setPath(path).setParameter("filename", filename).setPort(port) .build(); HttpPost httpPost = new HttpPost(uri); FileEntity fileEntity = new FileEntity(new File(localPath)); fileEntity.setChunked(true); httpPost.setEntity(fileEntity); httpPost.addHeader("Cookie", cookie); HttpResponse response = httpClient.execute(httpPost); HttpEntity httpEntity = response.getEntity(); httpEntity = new BufferedHttpEntity(httpEntity); String resultString = EntityUtils.toString(httpEntity); return resultString; } public static void main(String[] args) { try { UploadTest test = new UploadTest( "192.168.2.177", "XXXXX", "XXXXX", 443); String resultString = test.uploadFile( "/Users/justyoung/Desktop/upload/test.java", "mytest1"); System.out.println(resultString); } catch (URISyntaxException | IOException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } }

完。

转载于:https://my.oschina.net/boltwu/blog/550136

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/109195.html原文链接:https://javaforall.net

(0)
上一篇 2021年9月11日 下午8:00
下一篇 2021年9月11日 下午9:00


相关推荐

  • AcWing 2060. 奶牛选美(双端队列BFS)

    AcWing 2060. 奶牛选美(双端队列BFS)题目描述 听说最近两斑点的奶牛最受欢迎 约翰立即购进了一批两斑点牛 不幸的是 时尚潮流往往变化很快 当前最受欢迎的牛变成了一斑点牛 约翰希望通过给每头奶牛涂色 使得它们身上的两个斑点能够合为一个斑点 让它们能够更加时尚 牛皮可用一个 N MN MN M 的字符矩阵来表示 如下所示 XXXX XXX XXXX XX XXXX XXX XXXXX XXX 其中 X 表示斑点

    2025年11月6日
    4
  • apap图像全景拼接

    apap图像全景拼接文章目录基本原理图像配准关于最小割关于最大流apap的实现流程代码实现实验场景场景一场景二遇到的问题基本原理图像配准图像配准(apap)是将两张场景相关的图像进行映射,寻找其中的关系,多用在医学图像配准、图像拼接、不同摄像机的几何标定等方面,其研究也较为成熟。OpenCv中的stitching类就是使用了2007年的一篇论文(Automaticpanoramicimagestitchi…

    2026年2月18日
    8
  • python的zipfile.open_python之zipfile[通俗易懂]

    python的zipfile.open_python之zipfile[通俗易懂]1简述zip文件是一个常用的归档和与压缩标准。zipfile模块提供了创建、读取、写入、添加及列出zip文件的工具。zipfile里有2个非常常用的class,分别是Zipfile和ZipInfo,在绝大多数情况下,我们只需要使用这2个class就可以了。Zipfile是主要的类,用于创建和读取zip文件,而ZipInfo是储存zip文件每个信息的。2Zipfile基本操作1创建一个zip对…

    2025年12月8日
    5
  • android p是哪个版本,Android P是什么系统?Android P与Android有什么区别?[多图][通俗易懂]

    对于AndroidP系统,是一个既熟悉又陌生的概念,网上关于AndroidP爆料很多,但具体是什么系统,与Android系统有什么区别都不太清楚。随着一年一度的古哥I/O2018开发者大会的正式召开。AndroidP系统也渐渐解开了大家的问题,具体分析如下。这次大会,算是底层系统的更新,配合手机厂商的深度定制将会带来焕然一新的使用体验。全新的AndroidP开发者预览版正式加入…

    2022年4月6日
    42
  • [面试分享]想跳槽涨薪,想进大厂,如何准备面试呢?

    [面试分享]想跳槽涨薪,想进大厂,如何准备面试呢?

    2022年2月19日
    48
  • 为什么使用OpenClaw叫做"养龙虾"?

    为什么使用OpenClaw叫做"养龙虾"?

    2026年3月13日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号