自理解Https原理:证书传递,握手信息传递,数据加密解密的分析。

导读
Https协议其实就是在原先的Http应用层协议上面加了一套TLS/SSL协议,也就是在Http协议上了加了一套加密的模块。
服务器和客户端的信息都会通过TLS来进行加密,传输的数据都是加密的数据,具体是怎么加密,解密和验证服务器的
是在几次握手之后来确定的。
几次握手的示意图

握手图

握手详情
  • 1.第一次客户端发送一个url发送到服务器端,这里面包含客户端能支持的加密算法。
  • 2.服务器拿到客户端发过来的信息,是否匹配客户端支持的加密的算法,如果不支持则直接失败。服务器会自己的一套公钥,私钥,证书,公钥是用来加密的,私钥是用来解密的。证书可以自己生成也可以向可信机构申请(自己申请的会弹出弹框需要用户进行信任)。服务器传给客户端的信息包括一套HASH算法,公钥,证书颁发机构,证书过期时间等信息。
  • 3.客户端接受到证书之后,会判断证书是否过期,是否可信。如果都可以的话,客户端会生成一个随机值,其实也就是加密算法的一个规则。客户端会根据预定的hash算法对要传送的握手信息取Hash值。然后把握手消息和握手消息的hash值通过随机数进行加密。然后把随机值通过公钥加密和对称加密后的握手信息发给服务器。
  • 4.服务器接受到公钥加密的信息和对称加密的握手信息之后,服务器先用私钥解析拿到传输的随机数和握手信息。解密之后在对握手信息和随机数取的hash值,然后判断和客户端传来是是否一致。然后在用随机密码和握手信息生成hash值发给客户端。
  • 5.客户端对称解密,拿到信息,再次生成hash值,然与服务器做对比,如果一致,则握手结束,以后都使用对称加密来传递数据。

    取Hash值的目的就是为了验证在数据传递的路途中是否被人篡改过。

  • 6.这时间客户端和服务端就可以通过对称加密来进行数据传递了,因为只有他们知道是如何进行对称加密的,并且加密的钥匙传递的时候也是安全的。所以即使拿到加密的信息也是无法看的懂得。

  • 握手过程中如果有任何错误,都会使加密连接断开,从而阻止了隐私信息的传输。

Android 端如何使用Https

这里网上找的洪洋大神的blog。
Android Https相关完全解析 当OkHttp遇到Https

通过这里了解到,在Android当中默认的是支持Https的,但是支持的都是CA机构颁发的证书,如果是自己生成的正式的话,那么就在访问的时候会出错。自签名的正式是不被信任的,就像访问12306一样说是不安全的,这时间我们Android这边需要做的就是和网页一样,高级设置继续前往即可(就是让客户端信任服务器的证书。)
* OkHttp的做法:
1.首先把我们下载的srca.cer放到assets文件夹下,其实你可以随便放哪,反正能读取到就行。
2.需要用代码进行设置信任此证书。

public void setCertificates(InputStream... certificates)
        {
try
{
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null);
    int index = 0;
    for (InputStream certificate : certificates)
    {
        String certificateAlias = Integer.toString(index++);
        keyStore.setCertificateEntry(certificateAlias, certificateFactory.generateCertificate(certificate));

        try
        {
            if (certificate != null)
                certificate.close();
        } catch (IOException e)
        {
        }
    }

    SSLContext sslContext = SSLContext.getInstance("TLS");

    TrustManagerFactory trustManagerFactory = 
        TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 

    trustManagerFactory.init(keyStore);
    sslContext.init
        (   
            null, 
            trustManagerFactory.getTrustManagers(), 
            new SecureRandom()
        );
   mOkHttpClient.setSslSocketFactory(sslContext.getSocketFactory());


} catch (Exception e)
{
    e.printStackTrace();
} 

}

  • 由于本人的公司也是很穷,某宝买的证书,学习过之后才是也是自签名的,不被客户端信任,所以客户端也需要配置,自家网络请求是老大封装好的HttpUrlConnection,配置如下:

    private String doPostNoFile() throws MalformedURLException, IOException, ProtocolException, UnsupportedEncodingException, FileNotFoundException, CertificateException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
    String result = null;
    URL url1 = new URL(this.url);
    if(this.urlRequestType == 0) {
        this.conn = (HttpURLConnection)url1.openConnection();
        this.initConn(this.conn);
        this.conn.setRequestMethod("POST");
        this.conn.setRequestProperty("Content-Type", this.DEFAULT_FROM_DATA);
        this.out = this.conn.getOutputStream();
    } else {
        CertificateFactory buf = CertificateFactory.getInstance("X.509");
        InputStream line = this.context.getAssets().open("ssl-bundle.crt");
        Certificate buffer = buf.generateCertificate(line);
        KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
        keystore.load((InputStream)null, (char[])null);
        keystore.setCertificateEntry("ca", buffer);
        String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
        tmf.init(keystore);
        SSLContext context = SSLContext.getInstance("TLS");
        context.init((KeyManager[])null, tmf.getTrustManagers(), (SecureRandom)null);
        this.urlConnection = (HttpsURLConnection)url1.openConnection();
        this.urlConnection.setSSLSocketFactory(context.getSocketFactory());
        this.initConn(this.urlConnection);
        this.urlConnection.setRequestMethod("POST");
        this.urlConnection.setRequestProperty("Content-Type", this.DEFAULT_FROM_DATA);
        this.out = this.urlConnection.getOutputStream();
         }
      }
    }
    
总结:

通过以上学习,理解了Https的原理,也明白了客户端这边改如何去处理自信任证书。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值