iOS https

公司使用https,但是与后台调试接口的时候却死活调试失败。我在Safari打开他们的接口,发现证书不匹配的警告,于是就判定是他们证书配置有问题,后来发现果然是这个问题。
总结下iOS使用https的问题
用HTTPS有个问题,就是CA证书。缺省情况下,iOS要求连接的HTTPS站点必须为CA签名过的合法证书,AFNetworking是个iOS上常用的HTTP访问库,由于它是基于iOS的HTTP网络通讯库,自然证书方面的要求和系统是一致的,也就是你需要有一张合法的站点证书。
  正式的CA证书非常昂贵,很多人都知道,AFNetworking2只要通过下面的代码,你就可以使用自签证书来访问HTTPS
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
securityPolicy.allowInvalidCertificates = YES;
  这么做有个问题,就是你无法验证证书是否是你的服务器后端的证书,给中间人攻击,即通过重定向路由来分析伪造你的服务器端打开了大门。

浏览器中https验证流程###

1   客户端输入网址https://www.domain..com,连接到server的443端口。
2   服务器返回一个证书(包含公钥、和证书信息,如证书的颁发机构,过期时间等),证书由服务器所拥有的私钥非对称加密生成。
3   客户端对证书进行验证(首先会验证证书是否有效,比如颁发机构,过期时间等等)。
4   如果客户端验证通过,客户端生成一个随机数,在用服务器返回的证书(公钥)进行加密传输。
5   因为公钥是通过服务器的私钥生成,所以服务器是可以对客户端的传回的加密数据进行对称解密的。服务器拿到由客户端生成的随机数,对要传递的数据使用随机数加密。
6   客户端收到服务器使用随机数加密的数据进行解密。

不过在app的开发中因为我们的app通常只需要和一个服务器端进行交互,所以不必要每次请求都从服务器那边获取证书(公钥),在开发中app直接将服务器对应生成的证书(公钥)放在沙盒中,HTTPS请求时只要直接和服务器返回的证书(公钥)进行比对。如果验证通过则使用公钥进行加密在传递回服务器。
这样即使app中的证书(公钥)被截取,中间人使用证书冒充了服务器与客户端进行通信时(通过了验证),但因为从app返回的数据都是通过证书(公钥)加密的。而中间人从app截取的证书时公钥,缺少对应的私钥即使截获了信息也无法解密。能够最大的程度的保护传递的信息安全。
从上面的通信过程中,最重要的是存储在服务器的私钥。因为只有私钥生成了在通信过程中传递的证书(公钥),且只有通过私钥才能对公钥加密的信息进行解密,所以在开发过程中保护好私钥的安全。
代码介绍:

/**
 SSL身份认证

 @return
 */
+ (AFSecurityPolicy *)customSecurityPolicy{

    // 导入证书 仅支持cer 格式 需要将crt格式转换下  //转换格式 openssl x509 -in 你的证书.crt -out 你的证书.cer -outform der
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"2__.gongfupay.com" ofType:@"cer"];
    NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
    // AFSSLPinningModeCertificate 使用证书验证模式
    // AFSSLPinningModeNone 这个模式表示不做SSL pinning,只跟浏览器一样在系统的信任机构列表里验证服务端返回的证书。若证书是信任机构签发的就会通过,若是自己服务器生成的证书就不会通过。
    // AFSSLPinningModeCertificate 这个模式表示用证书绑定方式验证证书,需要客户端保存有服务端的证书拷贝,这里验证分两步,第一步验证证书的域名有效期等信息,第二步是对比服务端返回的证书跟客户端返回的是否一致。
    // AFSSLPinningModePublicKey 这个模式同样是用证书绑定方式验证,客户端要有服务端的证书拷贝,只是验证时只验证证书里的公钥,不验证证书的有效期等信息。只要公钥是正确的,就能保证通信不会被窃听,因为中间人没有私钥,无法解开通过公钥加密的数据。
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    // allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO 如果是需要验证自建证书,需要设置为YES
    securityPolicy.allowInvalidCertificates = YES;

    //是否需要验证域名,默认为YES
    //假如证书的域名与你请求的域名不一致,需把该项设置为NO;如设成NO的话,即服务器使用其他可信任机构颁发的证书,也可以建立连接,这个非常危险,建议打开。
    //置为NO,主要用于这种情况:客户端请求的是子域名,而证书上的是另外一个域名。因为SSL证书上的域名是独立的,假如证书上注册的域名是www.google.com,那么mail.google.com是无法验证通过的;当然,有钱可以注册通配符的域名*.google.com,但这个还是比较贵的。
    //如置为NO,建议自己添加对应域名的校验逻辑。
    securityPolicy.validatesDomainName = NO;

    [securityPolicy setPinnedCertificates:@[cerData]];
    return securityPolicy;
}

AFHTTPSessionManager调用setSecurityPolicy方法 进行身份验证

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 原文地址:iOS安全系列之一:HTTPS 如何打造一个安全的App?这是每一个移动开发者必须面对的问题。在移动Ap...
    violafa阅读 4,330评论 0 2
  • 原文地址 http://blog.csdn.net/u012409247/article/details/4985...
    0fbf551ff6fb阅读 8,943评论 0 13
  • 快速适配直接看下面的示例代码吧,概念有点多。。。 自己客户端生成证书放在服务器上,可以自签服务器必须ca签署,服务...
    _YZG_阅读 13,721评论 0 56
  • 一、作用 不使用SSL/TLS的HTTP通信,就是不加密的通信。所有信息明文传播,带来了三大风险。 (1)窃听风险...
    XLsn0w阅读 13,702评论 2 44
  • 背景 谷歌从 2017 年起,Chrome 浏览器将也会把采用 HTTP 协议的网站标记为「不安全」网站;苹果从 ...
    人魔七七阅读 7,519评论 2 8

友情链接更多精彩内容