https数据传输协议(安全套接字层超文本传输协议)

https(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。 它是一个URI scheme(抽象标识符体系),句法类同http:体系。用于安全的HTTP数据传输。https:URL表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。

https主要作用可以分为两种:一种是建立一个信息安全通道,来保证数据传输的安全;另一种就是确认网站的真实性,凡是使用了 https 的网站,都可以通过点击浏览器地址栏的锁头标志来查看网站认证之后的真实信息,也可以通过 CA 机构颁发的安全签章来查询。

http超文本传输协议 下面我们来说一下他们2个的区别:

HTTPS和HTTP的区别
超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。
为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
HTTPS和HTTP的区别主要为以下四点:
一、https协议需要到ca申请证书,一般免费证书很少,需要交费。
二、http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
三、http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
四、http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

下面我们来撸一下代码
https一个不负责的请求类

public class HttpUtilsUnSafe {
    private static HttpUtilsUnSafe httpUtils;

    public HttpUtilsUnSafe() {
    }

    public static  HttpUtilsUnSafe getInstance() {
        if(httpUtils==null){
            new HttpUtilsUnSafe();
        }

        return httpUtils;
    }
    public interface OnRequestCallBack{
        void onSuccess(String s);
        void onFail(Exception e);
    }
    public void get(final String path, final OnRequestCallBack callBack){
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url=new URL(path);
                    //1.改成s
                    HttpsURLConnection conn= (HttpsURLConnection) url.openConnection();
                    //2.SSLContext初始化
                    //TLS是SSl的第二版加密方式
                    SSLContext tls = SSLContext.getInstance("TLS");
                    TrustManager[] trustManagers={};
                    tls.init(null,trustManagers,new SecureRandom());
                    //3.ssl工厂
                    SSLSocketFactory factory = tls.getSocketFactory();
                    conn.setSSLSocketFactory(factory);
                    conn.setRequestMethod("GET");
                    conn.setReadTimeout(5000);
                    conn.setConnectTimeout(5000);
                    conn.setDoInput(true);
                    conn.setDoOutput(true);
                    conn.connect();

                    InputStream inputStream = conn.getInputStream();
                    StringBuilder sb=new StringBuilder();
                    int flag;
                    byte[] by=new byte[1024];
                    while((flag=inputStream.read(by))!=-1){

                        sb.append(new String(by,0,flag));
                    }
                    String s=sb.toString();
                    //调用对方传入callback完成回调操作
                    callBack.onSuccess(s);



                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (NoSuchAlgorithmException e) {
                    e.printStackTrace();
                } catch (KeyManagementException e) {
                    e.printStackTrace();
                    callBack.onFail(e);
                }
            }
        }).start();


    }
}

https一个负责任的请求类

public class HttpUtilsSafe {
    private static HttpUtilsSafe httpUtilsSafe;

    private HttpUtilsSafe() {
    }

    public static HttpUtilsSafe getInstance() {
        if (httpUtilsSafe == null) {
            httpUtilsSafe = new HttpUtilsSafe();
        }
        return httpUtilsSafe;
    }

    public interface OnRequestCallBack {
        void onSuccess(String s);

        void onFail(Exception e);
    }

    public void get(final Context context, final String path, final OnRequestCallBack callBack) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    URL url = new URL(path);
                    //1.改成s
                    HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
                    //2.SSLContext初始化
                    SSLContext tls = SSLContext.getInstance("TLS");
                    MyX509TrustManager myX509TrustManager = new MyX509TrustManager(getX509Certificate(context));
                    TrustManager[] trustManagers = {myX509TrustManager};
                    tls.init(null, trustManagers, new SecureRandom());
                    //3.ssl工厂
                    SSLSocketFactory factory = tls.getSocketFactory();
                    //4.添加一个主机名称校验器
                    conn.setHostnameVerifier(new HostnameVerifier() {
                        @Override
                        public boolean verify(String hostname, SSLSession sslSession) {
                            if (hostname.equals("kyfw.12306.cn")) {
                                return true;
                            } else {
                                return false;
                            }
                        }
                    });


                    conn.setSSLSocketFactory(factory);
                    conn.setRequestMethod("GET");
                    conn.setReadTimeout(5000);
                    conn.setConnectTimeout(5000);
                    conn.setDoInput(true);
                    conn.setDoOutput(true);
                    conn.connect();
                    InputStream inputStream = conn.getInputStream();

                    StringBuilder sb = new StringBuilder();
                    int flag;
                    byte[] buf = new byte[1024];
                    while ((flag = inputStream.read(buf)) != -1) {
                        sb.append(new String(buf, 0, flag));
                    }
                    String s = sb.toString();
                    //调用对方传入callback完成回调操作
                    callBack.onSuccess(s);
                } catch (Exception e) {
                    e.printStackTrace();
                    callBack.onFail(e);
                }

            }
        }).start();

    }

    //拿到自己的证书
    X509Certificate getX509Certificate(Context context) throws IOException, CertificateException {
        InputStream in = context.getAssets().open("srca.cer");
        CertificateFactory instance = CertificateFactory.getInstance("X.509");
        X509Certificate certificate = (X509Certificate) instance.generateCertificate(in);
        return certificate;


    }
}

对于那种需要证书的,就需要安装证书
我们就以12306为例:

https数据传输协议(安全套接字层超文本传输协议)_第1张图片

下载完证书解压下包,之后会有jar包https数据传输协议(安全套接字层超文本传输协议)_第2张图片

之后在自己的as(androidstudio)main文件中建一个assets文件夹

这里写图片描述

然后在代码中需要用到 X509TrustManager它是一个接口,需要自己
写个类来实现下;

这个是不安全的

public class MyX509TrustManagerUnSafe implements X509TrustManager {
    @Override
    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

    }

    @Override
    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
}

针对安全的

package com.example.httpsrequest_master.http;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.X509TrustManager;

/**
 * Created by 亮亮 on 2017/11/7.
 */

public class MyX509TrustManager implements X509TrustManager {
    //如果需要对证书进行校验,需要这里去实现,如果不实现的话是不安全
    X509Certificate mX509Certificate;

    public MyX509TrustManager(X509Certificate mX509Certificate) {
        this.mX509Certificate = mX509Certificate;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {

    }

    @Override
    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
        for (X509Certificate certificate : x509Certificates) {
            //检查证书是否有效
            certificate.checkValidity();
            try {
                certificate.verify(mX509Certificate.getPublicKey());
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (NoSuchProviderException e) {
                e.printStackTrace();
            } catch (SignatureException e) {
                e.printStackTrace();
            }
        }

    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return new X509Certificate[0];
    }
}

下面看一下效果图吧:

https数据传输协议(安全套接字层超文本传输协议)_第3张图片

我想你们应给能看懂点击button显示textView。。。
下回再见,希望多多指教啊
~~~~

你可能感兴趣的:(android,http通信,安全,超文本传输协议)