• iOS https 证书信任漏洞解决办法


    Xcode7版本开始默认使用https通讯协议,由于我在的公司从属金融行业,对通讯安全要求比较高,公司要求客户端在涉及敏感操作的接口使用https协议进行请求。
     
    但是单纯使用https请求其实也是不安全的,至于为什么不安全请参考这篇文章:http://www.tuicool.com/articles/b2AnMv
    (这篇文章里面有安卓如何解决这个漏洞,所以做安卓的有福了,代码直接可以贴过去用,但是iOS就没有这么幸运了)
     
    所以公司要求我们把证书公钥写进客户端,这个公钥有俩作用,一是客户端每次与服务器通讯前,先比对服务器返回的公钥与客户端本地存的公钥是否一样,一样的话再继续与服务器通讯,不一样,就拒绝呗;二是客户端用公钥对数据进行加密,服务器端用私钥进行解密。这样,就能保证数据不会被抓包工具抓到啦。
     
     
    但是对于我这样的小白来说,难度还是很大的。例如:怎么拿到.cer文件,怎么把.cer文件写入代码,怎么比对服务器给我返回的公钥与我存的公钥是否一致,用什么方法,在哪个环节对参数进行rsa加密。。。
     
    我问了很多心目中的大神,还有本渣的同学。。。他们有些甚至完全不理解这个需求是什么意思。。。还有些已经不想再搭理总问白痴问题的本渣了。。。嘤嘤嘤嘤嘤~~所以我只能自己查资料了。
     
     我冥思苦想了好久该怎么做还是毫无头绪,直到————接着往下看吧。
     
    废话不多说了,我就从小白的角度说一下我是怎么完成这个艰巨任务的吧。

    首先要声明一下我请求接口数据用的是第三方类:AFNetworking进行网络请求,以前不懂AFNetworking的强大,用到它的功能只是冰山一角,根本谈不上对这个第三方有什么理解,只是简单用一下它的post或get请求,这次通过使用它的https请求方法,又对它多了一点点了解。
     
    第一步:对项目的.plist文件进行设置,具体内容如下
    发现贴图片会比较坑,那我就贴代码吧,plist里面的代码复制出来成了介个样子:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
    <key>NSExceptionDomains</key>
    <dict>
    <key>item 0</key>
    <string>xxxx.xxxxxxx.com.cn</string>
    <key>item 1</key>
    <string>xxxx.xxxxxx.com</string>
    <key>item 2</key>
    <string>xxxx.xxxxx.com</string>
    </dict>
    </dict>
    </plist>
    我来解释一下这是在做什么:我做的这个项目不同的版块需要向不同的服务器请求数据,有的涉及敏感信息,必须使用https请求,其他的的一些无关紧要的,依然可以使用http请求。
    所以,我的设置如下:
    allow arbitrary loads 设置为yes 就是说我们这个app还是允许使用http请求的,相信大家都知道这个。
    exception domains:例外的域名,也就是说,这个字典里设置的是必须使用https协议的域名。所以,就把需要进行https请求的域名添加进去咯。
    这样设置以后,正好可以达到公司的要求:敏感操作的接口使用https请求,但是其他的可以使用http请求。好吧至少大部分满足了。
     
    第二步:弄到.cer证书
    比方说,你家服务器的域名是www.xxxxxx.com,那你就去IE浏览器访问https://www.xxxxxx.com这个网址,右键>>>属性>>>证书>>>详细信息>>>复制到文件,这样你就把证书下载到电脑里啦。(这个过程中可能会遇到“复制到文件”按钮不能点击的情况,可能是IE浏览器版本的问题,我使用的8.0.7601.17514版本是可以的~~)当然你有别的方法可以弄到这个.cer文件也是OK的。
     
    第三步:把.cer证书导入工程。这一步很简单啦,跟导入别的文件一样的步骤。
     
    第四步:代码部分:把.cer文件写入代码里面。
     
    关键代码如下:

    - (void)requestWithCerByManager:(AFHTTPRequestOperationManager *)manager {

        NSString *cerPath= [[NSBundle mainBundle] pathForResource:@"www" ofType:@".cer"];

        if (cerPath.length) {

            NSData *certData = [NSData dataWithContentsOfFile:cerPath];

            AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModePublicKey];

            [securityPolicy allowInvalidCertificates];

            [securityPolicy setPinnedCertificates:@[certData]];

            /**** SSL Pinning ****/

            manager.securityPolicy = securityPolicy;

        } else {

            // do nothing

        }

    }

    然后在请求数据的方法里,初始化manager之后,直接调用这个方法就好啦。

     
    OK,这样基本上就可以啦~
    另外用公钥(public key)对参数进行RSA加密的工作也不需要我们自己动手啦,af已经很贴心的帮我们完成了。
     
    至于验证是否处理成功的方式嘛,可以两步进行:
    第一步:查看经过处理的接口是否能够请求成功;
    第二步:第一步OK的话,就对app进行抓包,看看能不能抓取到手机与服务器在相关接口通讯的数据。如果抓不到,那就是成功啦。
     
    声明:
    一、本人纯小白一枚,通过培训机构走出来的小渣渣,大学里学习的内容跟计算机和互联网八杆子打不着的文科生。如果哪些地方表现的比较外行,请勿喷哦。
    二、本渣主要参考的资料来自:http://blog.cnbang.net/tech/2416/ 另外本渣把项目里的AFSecurityPolicy.m文件也替换成了这篇文章里的.m文件。
    三、本渣的项目涉及多个域名,所以- (void)requestWithCerByManager:(AFHTTPRequestOperationManager *)manager这个方法里面要根据请求服务器的不同,写入不同的.cer文件哦,这里要提醒有相似需求的同学们注意一下啦。
     
    OK, DONE;
    从今以后本渣也是写过技术博客的人啦。
    hia hia hia 飘走。
    喝最烈的酒,看最美的风景。
  • 相关阅读:
    6、linux中同步、互斥、阻塞(原子操作、信号量、阻塞)
    lightOJ-1199 Partitioning Game (SG函数)
    HDU-1013 Digital Roots
    HDU-1004 Let the Balloon Rise (STL map)
    HDU-1020 Encoding (字符串)
    POJ-2524 Ubiquitous Religions (并查集)
    POJ-1988 Cube Stacking (带权并查集)
    POJ-2236 Wireless Network (并查集)
    HDU-1002 A + B Problem II (模拟大数相加)
    HDU-1829 A Bug's Life (种类并查集)
  • 原文地址:https://www.cnblogs.com/mona/p/5085807.html
Copyright © 2020-2023  润新知