Android Https解析

一、Https基础

    1、Http的缺点

        1)、通信报文是明文,内容容易被窃听

        2)、没有通信方的身份,通信方容易被伪装

        3)、无法验证报文的完整性,因此内容可能已经被更改

    2、Https可以解决上面缺点。Https就是Http+ssl。Http直接和tcp通信,Https是和ssl通信,ssl和tcp通信。ssl是独立于http的协议。结构如下:

Android Https解析_第1张图片

    3、Https的加密机制

        1)、共享密码加密

         使用同一密码加密和解密的方式叫作共享密码加密,又叫对称米要加密。

         问题:共享密码加密方式怎么把密钥给客户端?如果攻击者获得了密钥加密就失去意义了。

         优点:加密解密速度较快

        2)、公开密钥加密

        公开密钥加密使用一对非对称的密钥,一把是私钥,一把是公钥。 私钥不能给其他人,公钥可以给任何人。又叫非对称加密。

        问题:速度较慢

        优点:不用担心攻击者或者加密密钥,因为公钥本来就要给别人的。

        3)、https加密机制

        https在交换密钥环节使用公开密钥加密,然后通信时使用共享密钥加密。这样就综合了两者的优点,即保证了通信的速度,又保证了密钥的安全。

    4、证书公开密钥正确性的证书

    公开密钥加密还是有问题:无法证明公开密钥本身是货真价实的公开密钥。为了解决这个问题可以使用由数字证书认证机构(CA)和其他机关颁发的公开密钥证书。数字认证机构的业务流程:

    1)、服务器的运营人员向数字认证机构提出公开密钥申请。认证机构判明申请者身份后对已申请的公开密钥做数字签名,然后分配这个已签名的公开密钥,并将公开密钥放入公钥证书中后绑定在一起。

    2)、服务器将认证机构颁发的公钥证书发给客户端。

    3)、客户端使用认证机构的公开密钥验证证书上的数字签名,验证通过表示服务器的公开密钥是可信赖的。

注意:多数浏览器会事先在内部植入认证机关的公开密钥

     5、通信流程

    1)、浏览器将自己支持的一套加密算法、HASH算法发送给网站。

    2)、网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。

    3)、浏览器获得网站证书之后,开始验证证书的合法性,如果证书信任,则生成一串随机数字作为通讯过程中对称加密的秘钥。然后取出证书中的公钥,将这串数字以及HASH的结果进行加密,然后发给网站。

    4)、网站接收浏览器发来的数据之后,通过私钥进行解密,然后HASH校验,如果一致,则使用浏览器发来的数字串使加密一段握手消息发给浏览器。

    5)、浏览器解密,并HASH校验,没有问题,则握手结束。接下来的传输过程将由之前浏览器生成的随机密码并利用对称加密算法进行加密。

Android Https解析_第2张图片

二、Android访问自签名网站

      1、生成自签名证书

     1)、为服务器生成证书

keytool -genkey -v -alias tomcat -keyalg RSA -keystore D:\home\tomcat.keystore -validity 36500 (参数简要说明:“D:\home\tomcat.keystore”含义是将证书文件的保存路径,证书文件名称是tomcat.keystore ;“-validity 36500”含义是证书有效期,36500表示100年,默认值是90天 “tomcat”为自定义证书名称)。

     2)、为客户端生成证书

keytool -export -alias tomcat -file D:/home/tomcat.cer -keystore D:\home\tomcat.keystore -validity 36500 

如果要通过浏览器访问则需要选择“受信任的根证书颁发机构”加入该证书。

      2、配置tomcat

配置tomcat server.xml: 
                 maxThreads="150" SSLEnabled="true" scheme="https" secure="true" 
               clientAuth="false" sslProtocol="TLS" keystoreFile="D:/home/tomcat.keystore" keystorePass="123456"  />

    3、android okhttp配置

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();
    } 

}

certificates是证书文件,把客户端证书文件放在asserts目录中,然后

getAssets().open("tomcat.cer")

 获取certificates

    4、使用字符串替换客户端证书

使用命令:keytool -printcert -rfc -file tomcat.cer

得到结果如下:

-----BEGIN CERTIFICATE-----
MIIDhTCCAm2gAwIBAgIERZ1R+jANBgkqhkiG9w0BAQsFADByMRAwDgYDVQQGEwdVbmtub3duMRAw
DgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYD
VQQLEwdVbmtub3duMRYwFAYDVQQDEw0xOTIuMTY4LjIuMTIwMCAXDTE4MDgwNDAzNTg1MFoYDzIx
MTgwNzExMDM1ODUwWjByMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYD
VQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRYwFAYDVQQD
Ew0xOTIuMTY4LjIuMTIwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs28HTASh4/fm
S83jpFzBT6lbYz4mgbw2AqE3HRHzcSBGrjKqov+nPXgELKZUqAaLBH0juWVTwv2rXf2dNekbEOz9
wA2aMW4YycfQFJ4Yvgd1SmtAVbI3D4fE0ewf7R+CtV8PTlUWBW2O1TH/7UY2BamqYlILUR4gM4rA
yfR37bFu8EveMbSgkUgbg3RHWxap7VsUdO2t5NTCOUFjue3DW0cbkzvv1HbDOv+nyTuKIwFQ1UDA
e2xu7IG4e+m80y4Lo++U64nsWxSBWUiJ0zXx2Oek08eBG51KydCXh3THDRwzHa1ahQdfdYSVliRZ
LBwNd4XXjgapGCdNoDcyQYbTLQIDAQABoyEwHzAdBgNVHQ4EFgQU0Qp8G8OgoZwzWQar/Kgjm1CC
CCUwDQYJKoZIhvcNAQELBQADggEBAAY/EsMzwmZhkKJ3ChhBzskxhnjtApY/a/4auQYG/wCVsBfC
kjZyXsv7CFJd1C5HtIAQklVcaDecJzshNM2KFb7cCIQjNUxkpF0Pkbaxs5oJywzR5fuOuPLvQA1l
mt52l6vis35s6gyTPAE9VkE12PXobxED7Gpj3NCogmMn5HQmPCKieHwiFU7Giwz/ypsjkz8vPK8T
m908vr9ja6l+FmQRyJhNf6SgAjeKOmYpcW0Np/pVYDMuz1IFW2Ty6h55TIGRTDPI0YIEcaP8w417
GZWXuBy4pfr1TVBWeqiEcoXsvqAgpG6deA7K3Ei96LGYDI+olI8yTMVH0+A0ROt5Ktg=
-----END CERTIFICATE-----

代码中使用:

public class MyApplication extends Application
{
    private String CER = "-----BEGIN CERTIFICATE-----
MIIDhTCCAm2gAwIBAgIERZ1R+jANBgkqhkiG9w0BAQsFADByMRAwDgYDVQQGEwdVbmtub3duMRAw
DgYDVQQIEwdVbmtub3duMRAwDgYDVQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYD
VQQLEwdVbmtub3duMRYwFAYDVQQDEw0xOTIuMTY4LjIuMTIwMCAXDTE4MDgwNDAzNTg1MFoYDzIx
MTgwNzExMDM1ODUwWjByMRAwDgYDVQQGEwdVbmtub3duMRAwDgYDVQQIEwdVbmtub3duMRAwDgYD
VQQHEwdVbmtub3duMRAwDgYDVQQKEwdVbmtub3duMRAwDgYDVQQLEwdVbmtub3duMRYwFAYDVQQD
Ew0xOTIuMTY4LjIuMTIwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAs28HTASh4/fm
S83jpFzBT6lbYz4mgbw2AqE3HRHzcSBGrjKqov+nPXgELKZUqAaLBH0juWVTwv2rXf2dNekbEOz9
wA2aMW4YycfQFJ4Yvgd1SmtAVbI3D4fE0ewf7R+CtV8PTlUWBW2O1TH/7UY2BamqYlILUR4gM4rA
yfR37bFu8EveMbSgkUgbg3RHWxap7VsUdO2t5NTCOUFjue3DW0cbkzvv1HbDOv+nyTuKIwFQ1UDA
e2xu7IG4e+m80y4Lo++U64nsWxSBWUiJ0zXx2Oek08eBG51KydCXh3THDRwzHa1ahQdfdYSVliRZ
LBwNd4XXjgapGCdNoDcyQYbTLQIDAQABoyEwHzAdBgNVHQ4EFgQU0Qp8G8OgoZwzWQar/Kgjm1CC
CCUwDQYJKoZIhvcNAQELBQADggEBAAY/EsMzwmZhkKJ3ChhBzskxhnjtApY/a/4auQYG/wCVsBfC
kjZyXsv7CFJd1C5HtIAQklVcaDecJzshNM2KFb7cCIQjNUxkpF0Pkbaxs5oJywzR5fuOuPLvQA1l
mt52l6vis35s6gyTPAE9VkE12PXobxED7Gpj3NCogmMn5HQmPCKieHwiFU7Giwz/ypsjkz8vPK8T
m908vr9ja6l+FmQRyJhNf6SgAjeKOmYpcW0Np/pVYDMuz1IFW2Ty6h55TIGRTDPI0YIEcaP8w417
GZWXuBy4pfr1TVBWeqiEcoXsvqAgpG6deA7K3Ei96LGYDI+olI8yTMVH0+A0ROt5Ktg=
-----END CERTIFICATE-----";

    @Override
    public void onCreate()
    {
        super.onCreate();

        OkHttpClientManager.getInstance()
                .setCertificates(new Buffer()
                        .writeUtf8(CER)
                        .inputStream());
}

 

你可能感兴趣的:(Android Https解析)