您的位置:首页 > 理论基础 > 计算机网络

NoHttp如何使用Https

2016-07-22 16:09 656 查看


NoHttp如何使用Https

QQ技术交流1群:46523908 

QQ技术交流2群:46505645 
NoHttp 源码及Demo托管在Github欢迎大家Star:https://github.com/yanzhenjie/NoHttp

NoHttp是专门做Android网络请求与下载的框架。直播视频和代码下载地址


分析

Android发起Https请求时分为两种情况,分为需要安全证书(从服务端获取的证书文件)和不需要安全证书两种情况。
NoHttp对于Https也很好的支持了,只需要为每一个请求设置SSLSocketFactory即可。


1. 需要证书的情况

首先需要一个SSLSocketFactory,下面是加载证书的代码,是Java和Android通用的,我们只需要SSLContext:
<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 拿到https证书SSLContext (NoHttp已经修补了系统的SecureRandom的bug)
*/</span>
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@SuppressLint</span>(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"TrulyRandom"</span>)
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> SSLContext <span class="hljs-title" style="box-sizing: border-box;">getSSLContext</span>() {
SSLContext sslContext = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
sslContext = SSLContext.getInstance(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"TLS"</span>);
<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 加载证书流, 这里证书需要放在assets下(<span style="color: rgb(85, 85, 85); font-family: 'microsoft yahei'; font-size: 14px; line-height: 35px;">从服务端获取的证书文件</span>)</span>
InputStream inputStream = Application.getInstance().getAssets().open(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"srca.cer"</span>);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 生成证书</span>
CertificateFactory cerFactory = CertificateFactory.getInstance(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"X.509"</span>);
Certificate cer = cerFactory.generateCertificate(inputStream);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 加载证书到KeyStore</span>
KeyStore keyStore = KeyStore.getInstance(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"PKCS12"</span>);
keyStore.load(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>);
keyStore.setCertificateEntry(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"trust"</span>, cer);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 把KeyStore放入keyManagerFactory</span>
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// KeyStore加入TrustManagerFactory</span>
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);

<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 初始化SSLContext</span>
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SecureRandom());
} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {
e.printStackTrace();
}

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> sslContext;
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li></ul>


2. 不需要证书情况

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 如果不需要https证书.(NoHttp已经修补了系统的SecureRandom的bug)
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> SSLContext <span class="hljs-title" style="box-sizing: border-box;">getDefaultSLLContext</span>() {
SSLContext sslContext = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">try</span> {
sslContext = SSLContext.getInstance(<span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"TLS"</span>);
sslContext.init(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> TrustManager[]{trustManagers}, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> SecureRandom());
} <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">catch</span> (Exception e) {
e.printStackTrace();
}
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> sslContext;
}

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 信任管理器
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> TrustManager trustManagers = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> X509TrustManager() {
<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">checkClientTrusted</span>(X509Certificate[] chain, String authType) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> CertificateException {
}

<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">checkServerTrusted</span>(X509Certificate[] chain, String authType) <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">throws</span> CertificateException {
}

<span class="hljs-annotation" style="color: rgb(155, 133, 157); box-sizing: border-box;">@Override</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> X509Certificate[] <span class="hljs-title" style="box-sizing: border-box;">getAcceptedIssuers</span>() {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> X509Certificate[<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>];
}
};

<span class="hljs-javadoc" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
* 域名验证
*/</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">final</span> HostnameVerifier HOSTNAME_VERIFIER = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> HostnameVerifier() {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">boolean</span> <span class="hljs-title" style="box-sizing: border-box;">verify</span>(String hostname, SSLSession session) {
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">true</span>;
}
};</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li></ul>


为Request对象设置SSLSocketFactory


需要证书

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">RequestQueue queue = NoHttp.newRequestQueue();
...

Request<String> httpsRequest = NoHttp.createStringRequest(httpsUrl, RequestMethod);
SSLContext sslContext = getSSLContext();
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (sslContext != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
httpsRequest.setSSLSocketFactory(socketFactory);
}
queue.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, httpsRequest, OnResponseListener);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li></ul>


不需要证书

<code class="language-java hljs  has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">RequestQueue queue = NoHttp.newRequestQueue();
...

Request<String> httpsRequest = NoHttp.createStringRequest(httpsUrl, RequestMethod);
SSLContext sslContext = getDefaultSLLContext();<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 方法见上文</span>
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span> (sslContext != <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>) {
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
httpsRequest.setSSLSocketFactory(socketFactory);
}
httpsRequest.setHostnameVerifier(HOSTNAME_VERIFIER);<span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">// 见上文</span>
queue.add(<span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, httpsRequest, OnResponseListener);</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li></ul>


好了, 收工, 我去赶最后一趟回家的车了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: