首页 > 学院 > 开发设计 > 正文

小白一步一步使用HTTPS

2019-11-06 10:05:25
字体:
来源:转载
供稿:网友

由于2017年初开始禁止未使用https的应用上架appstore,领导们开始考虑在我们的应用中使用https,这让我很头疼,以前听到过https,用httpwatch抓知乎、微信的包的时候都看到这些应用使用的都是https,对https感觉很熟悉,其实是一知半解的,这下要在应用中使用,看来必须要好好研究下了。

  下面是研究https在简书上搜索到的几篇优秀文章:

   http://www.jianshu.com/p/ce1557c1868d;

   http://www.jianshu.com/p/d79b37216558;

   http://www.jianshu.com/p/4494774963a9;

   http://www.jianshu.com/p/7cdd2324f639;

   要使用HTTPS肯定要知道一些概念,从上面几篇优秀文章里找出来几个必须要了解的概念:

   1.HTTP:一种明文传输协议,交互过程以及数据传输都没有进行加密,通信双方没有进行身份验证,通信过程容易遭到劫持、篡改的安全问题。

   2.SSL:安全套接层。

   3.HTTPS:只是一种在HTTP协议的基础上加了一层SSL的封装,之后具有了以下三个特征:

                                                                                                                                                                  数据完整性:数据传输经过完整性校验

                                                                                                                                                                  数据隐私性:数据经过加密

                                                                                                                                                                  身份认证:第三方不能伪造客户端或者服务端的身份

   4.对称加密:采用单密码加密,同一个密钥可以用来加密,也可以用来解密,简单理解就是加解密都是用的同一个秘钥。特点:体量小,算法公开,加密效率特别高。

   5.非对称加密:有2个秘钥,一个是公开的秘钥,一个是私有密钥,这两个是一对,互相配合加密和解密,公钥加密用私钥解密,私钥加密公钥解密。特点:速度慢,但是加          密很可靠

   6.CA 证书:其实就是XXX机构颁发的一个包含公钥和密钥的证书。

    

    下面用一张我画的图来理解下HTTPS的工作原理:

                                              

         

             第一步:client向service发送一条请求,告诉service,client支持哪种算法(比如:对称加密算法有DES,RC5,密钥交换算法有RSA和DH,摘要算法有md5和SHA等)

             第二步:service接收到client的消息后,分析之后,选择一种client支持的算法,把证书发送给client的,这个证书里面包含了一些证书的基本信息(例如:失效时间,名称,域名信息,公钥等)

             第三步:client接收到信息后,利用本地存在的数字证书对service的证书进行验证,如果验证失败,会弹出一个提示框来显示错误信息,验证通过,生成一个随机数,然后证书中的公钥进行加密,发送给service

            第四步:service接收到加密的随机数之后,用公钥进行解密,取出随机数,然后把这个随机数当做密钥对要加密的内容进行对称加密,发送给client

            第五步:client接收到service发送的密文,用之前保存的随机数作为密钥进行解密,还原密文

            第六步:之后client和service进行数据交互,利用那个随机数作为密钥进行加解密

         到这里对很多https的概念还是很迷茫,比如数字认证识什么东东,在第二步的时候client是怎么验证service的证书?,service怎么对client的身份做校验,然后就反反复复又查资料,上面的问题都可以在下面的博客中找到

            http://www.cnblogs.com/P_Chou/archive/2010/12/27/https-ssl-certification.html

  现在应该能到得到一个结论,证书可以由国际上公认的证书机构颁发,一般客户端的证书验证的应用程序对这些机构颁发的证书完全信任,不过一般情况下,我们会让客户端程序安装我们服务端的根证书,保证客户端可以信任我们的证书。

  好了,废话不多说,看代码        

/** * 初始化有证书的SSLContext * <p> * client.cer 是后台申请提供的,不包含密钥信息 * * @param context * @return * @throws NoSuchAlgorithmException * @throws IOException * @throws CertificateException * @throws KeyStoreException * @throws UnrecoverableKeyException * @throws KeyManagementException */public static SSLContext getSSLContextWithCer(Context context) throws NoSuchAlgorithmException, IOException, CertificateException, KeyStoreException, UnrecoverableKeyException, KeyManagementException {    //实例化SSLContext    SSLContext sslContext = SSLContext.getInstance("SSL");    // 从assets中加载证书,在HTTPS通讯中最常用的是cer/crt和pem    InputStream inputStream = context.getAssets().open("client.cer");    // 证书工厂    CertificateFactory cerFactory = CertificateFactory.getInstance("X.509");    Certificate cer = cerFactory.generateCertificate(inputStream);    // 密钥库    KeyStore keyStory = KeyStore.getInstance("PKCS12");    //没有密钥    keyStory.load(null, null);    // 加载证书到密钥库中    keyStory.setCertificateEntry("ass", cer);    // 密钥管理器    KeyManagerFactory kMFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());    kMFactory.init(keyStory, null);    // 信任管理器    TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());    tmFactory.init(keyStory);    //初始化sslContext    sslContext.init(kMFactory.getKeyManagers(), tmFactory.getTrustManagers(), new SecureRandom());    inputStream.close();    return sslContext;}

           

/** * 获取SSLContext * * @return * @throws NoSuchAlgorithmException * @throws KeyManagementException */public static SSLContext getSSLContextWithoutCer() throws NoSuchAlgorithmException, KeyManagementException {    // 实例化SSLContext    SSLContext sslContext = SSLContext.getInstance("SSL");    sslContext.init(null, new TrustManager[]{trustManagers}, new SecureRandom());    return sslContext;}/** * 自定义信任管理器 */PRivate static TrustManager trustManagers = new X509TrustManager() {    @Override    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {    }    @Override    public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {    }    @Override    public X509Certificate[] getAcceptedIssuers() {        return new X509Certificate[0];    }};//验证主机名public static HostnameVerifier hostnameVerifier = new HostnameVerifier() {    @Override    public boolean verify(String hostname, SSLsession session) {        // TODO Auto-generated method stub        return true;    }};

 

       


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表