HttpClient之Https请求

1、 Https通信介绍

       Https 即安全的超文本传输协议,最初是由网景公司创建,Https在Http上面提供了一个传输级的安全层,目前安全层所用的协议是SSL(Secure Socket Layer)和其继任者TLS(Transport Layer Security),SSL是一个比较复杂的协议,已有商用和开源的实现版本,例如OpenSSL。所有Http请求和响应数据在传输到网络前都由安全层进行加密,如下图是Https和Http的网络协议层。

       客服端与服务器在建立连接前,需要进行握手,握手过程可分为单向和双向认证两类。

(1)    单向认证

        客服端只对服务端身份进行认证,具体认证过程如下图:

(2)    双向认证

       客服端不仅对服务端身份进行认证,同时服务端也需要客服端发送自己的身份信息,对客服端进行认证,具体认证过程如下图:

2、JSSE介绍

       JSEE 全称Java Secure Socket Extension,提供了一个java版本的SSL 协议的框架和实现,包括数据加密、服务器认证、消息完整性校验及可选的客服端认证等功能。Java应用程序可以借助JSEE,方便地实现Https通信。            在JSEE API中,连接的端点类是SSLSocket和 SSLEngine,下图展示了用于创建SSLSocket和SSLEngine的类:

       了解socket编程的朋友,从图中应该很容易看出,客服端所用的SSLSocket由SSLSocketFactory创建,服务器用的SSLServerSocket由SSLServerSocketFactory创建,这两个factory由SSLContext创建,SSLContext对象创建后需要用KeyManger、TrustManger、SecureRandom进行初始化,分别对本文用到的几个类说明下,对其他类有兴趣的可以参考oracle JSSE官方文档。

       SSLSocket:继承java网络编程中Socket的作用,应用程序通过SSLSocket完成SSL握手、通信数据的收发等;

       SSLEngine:类同SSLSocket,比SSLSocket功能更强大,SSLSocket提供的是阻塞IO模型,SSLEngine能提供非阻塞的IO模型;

        KeyManger:用于管理密钥、证书等,通信的一端通过KeyManager获取密钥、证书传递给通信对方,对方验证证书获取密钥;

        TrustManger:用于管理信任材料,用于验证通信对等方的身份,传递的证书是否合法;

3、HttpClient发送Https请求

        借助JSSE,HttpClient对Https请求提供全面的支持,HttpClient 借助JSSE API创建SSLSocket,用于Https请求,相关的类如下图:

        SSLProtocolSocketFactory类的createSocket方法内部实现是调用SSLSocketFactory的createSocket方法创建SSLSocket的,如下图:

(1)、标准的Https请求实例

标准的Https请求跟Http请求没有任何差异,HttpClient执行请求时依据url来判断是Http还是Https请求,自动进行通信处理,如下实例:

HttpClienthttpclient = new HttpClient();

  GetMethod httpget = newGetMethod("https://www.verisign.com/");

  try {

    httpclient.executeMethod(httpget);

   System.out.println(httpget.getStatusLine());

  } catch (Exception e) {

    e.printStackTrace();

  } finally {

    httpget.releaseConnection();

  }

当客服端通过代理与服务器通信时,与标准请求相比,需要设置与代理服务器进行身份认证的参数,建立SSL隧道的工作由Httpclient完成,应用无须关注,如下实例:

  HttpClient httpclient = new HttpClient();

 httpclient.getHostConfiguration().setProxy("myproxyhost",8080);

  httpclient.getState().setProxyCredentials("my-proxy-realm"," myproxyhost",

  newUsernamePasswordCredentials("my-proxy-username","my-proxy-password"));

  GetMethod httpget = newGetMethod("https://www.verisign.com/");

  try {

    httpclient.executeMethod(httpget);

    System.out.println(httpget.getStatusLine());

  } catch (Exception e) {

    e.printStackTrace();

  } finally {

    httpget.releaseConnection();

  }

(2)、定制的Https请求

一般场景下,标准Https请求能满足应用需求,有些应用场景需要对SSL协议细节进行定制,例如客服端接收服务器自签名的证书、双向认证、或用其他第三方SSL库替换JSSE的实现等,可按照如下步骤实现定制Https请求:

第一步,提供一个定制的套接字工厂类,该类实现 org.apache.commons.

httpclient.protocol.SecureProtocolSocketFactory接口,该factory负责创建SSLSocket, 实现定制就在这步,后续几步是描述将定制的Socket用于Https请求中;

第二步,第一步创建的SocketFactory实例化 org.apache.commons.httpclient.protocol.Protocol类型对象,实例化时需要指明协议和端口字段,如下实例代码:

Protocolmyhttps = new Protocol("https", new MySSLSocketFactory(), 443);

第三步,可以请求的主机或协议类设置协议对象,当针对主机设置时,当请求注册的主机时,会用定制SocketFactory创建SSLSocketSocket,代码实例如下:

HttpClienthttpclient = new HttpClient();

httpclient.getHostConfiguration().setHost("www.whatever.com",443, myhttps);

GetMethodhttpget = new GetMethod("/");

try {

  httpclient.executeMethod(httpget);

  System.out.println(httpget.getStatusLine());

} catch(Exception e) {

  e.printStackTrace();

} finally{

  httpget.releaseConnection();

}

当针对https协议设置协议对象时,即所有https请求都会用定制的SocketFactory创建SSLSocketSocket,代码实例如下:

Protocol.registerProtocol("https",

newProtocol("https", new MySSLSocketFactory(), 443));

HttpClienthttpclient = new HttpClient();

GetMethodhttpget = new GetMethod("https://www.whatever.com/");

try {

  httpclient.executeMethod(httpget);

  System.out.println(httpget.getStatusLine());

} catch(Exception e) {

e.printStackTrace();

}  finally {

  httpget.releaseConnection();

}

针对https协议设置协议对象这种方式需要慎用,需要考虑应用所有的https请求是否都是可用相同的定制SSLSocket,可跟踪registerProtocol方法实现,在项目中就遇到乱用这种方式导致的问题:公司有个系统需要调用微信和支付宝相关的接口,两者都是Https请求,调用微信接口需要定制Socket,错误地针对https协议注册定制Socket,导致调用微信接口加载本地证书失败时,其他线程调用支付宝接口也出现失败,报错的异常堆栈一致。

(3)、开源的定制SocketFactory实例

Apath开源了相关的定制实例,可以参考EasySSLProtocolSocketFactoryStrictSSLProtocolSocketFactoryAuthSSLProtocolSocketFactory,其中AuthSSLProtocolSocketFactory就是定制双向认证的实例,看了前面的知识介绍理解这些实例代码就轻松了。定制这块还是很灵活的,甚至可定制SSLContext对象,即用其他第三方SSL协议实现。

4、参考资料

1、HTTP权威指南

2、https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/

JSSERefGuide.html

3、http://hc.apache.org/httpclient-3.x/sslguide.html

4、https://alvinalexander.com/java/jwarehouse/commons-httpclient-2.0.1/src/contrib/org/apache/commons/httpclient/contrib/ssl/index.shtml

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,654评论 18 139
  • 闲敲棋子落灯花。 这是君奉天踏入仙脚后脑子里出现的第一句话。 潇洒神逸的仙者背对他歪在榻上,未着发冠,一头白发自然...
    淮音阅读 323评论 1 1
  • 1.前列县在哪里?—— 医院的候诊室里,一大妈问旁边的一大叔:“前列县是哪个县啊,离这里远不远?” 大叔想了想,说...
    范末末阅读 446评论 0 0