随着互联网的发展,网站全面 https 化已经越来越被重视,做为 App 开发人员,从一开始就让 API 都走 SSL 也是十分必要的。但是光这样就足够了吗?

SSL 可以保护线上 API 数据不被篡改,但是防不了别有用心的发现你们 API,然后写脚本做一些事情。
 
Charles 的 SSL 代理
具体如何查看 SSL 的请求呢?可以使用 Charles 的 SSL 代理功能。
准备工作
下载安装最新版的 Charles(https://www.charlesproxy.com/),点开 Help -> SSL Proxying -> Install Charles Root Certificate on a Mobile Device (如下图)
 

然后会弹出一个提示框:

 
打开你的 iPhone 测试机,设置网络代理到上述地址(你电脑的 IP):
 

然后在 Safari 中(只能是 Safari)访问 http://charlesproxy.com/getssl,系统会打开描述文件安装界面,点击右上角的安装(需要输入密码)。
 
 

安装成功后,在
设置 ->
通用 ->
描述文件与设备管理 下会多出一行:

 
开启代理
iPhone 安装好描述文件后,加到 Charles。点击 Proxy 菜单下的 SSL Proxying Settings:

 
在弹出的窗口中添加你感兴趣的 HOST,点 OK 保存,然后就可以在 Charles 中看到 HTTPS 的请求数据了。
 

本文以常见的微博为例,可以看到微博启动后发了如下请求,并且可以看到明文数据:

 
SSL Pinning
上述方法的原理其实不复杂,Charles 在 iPhone 测试机上安装了它自己的一个 CA,于是手机会信任由它签发的证书。Charles 充当了一个中间人,详见https://www.charlesproxy.com/documentation/proxying/ssl-proxying/。如何绕开这种情况呢?当然只能让手机只信任特定证书加密的包,于是就有了 SSL Pinning。
实现方式
首先问下后台的运维人员要到后台服务的 SSL PEM 格式的公钥,如 cert.pem,一般是一个纯文本文件,如:
-----BEGIN CERTIFICATE-----
MIIG4jCCBcqgAwIBAgIQDsAf+l9f2W2Jkl9C21bgSjANBgkqhkiG9w0BAQsFADBE
MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMU
....
-----END CERTIFICATE-----

然后在命令行中使用 OpenSSL 工具链转换格式为 DER ( iOS 只能支持这个格式,注意!):

openssl x509 -outform der -in cert.pem -out cert.der

将文件添加到 Xcode 工程中去。如果使用 AFNetworking,那么实现将比较简单,下面以 AFNetworking 为例:

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:@"https://api.foo.com"];

NSString *cert = [[NSBundle mainBundle] pathForResource:@"cert" ofType:@"der"];
NSData *data = [[NSFileManager defaultManager] contentsAtPath:cert];
AFSecurityPolicy *policy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate
withPinnedCertificates:[NSSet setWithObjects:data, nil]];
manager.securityPolicy = policy;
...

从代码中可以看到,可以一次指定多个证书。

这样一来,App 只接受由指定证书加密的数据,其他数据会拒绝,如下图:

同时 App 端的表现是请求已取消。

网易云SSL证书服务提供云上证书一站式生命周期管理,与全球顶级的数字证书授权机构(CA,Certificate Authority)和代理商合作,为你的网站与移动应用实现 HTTPS 加密部署。

本文来自网易云社区,经作者谭歆授权发布。

原文地址:iOS SSL Pinning 保护你的 API

更多网易研发、产品、运营经验分享请访问网易云社区

最新文章

  1. iOS提交AppStore后申请加急审核
  2. Java的初始化块、静态初始化块、构造函数的执行顺序及用途探究
  3. iOS 数据库的增删改查(OC版)
  4. OCP笔记001
  5. css2--collapse
  6. js简化判断是否为手机访问
  7. 【吉光片羽】js横向滚动与浮动导航
  8. SharePoint 2013 JavaScript 对象判断用户权限
  9. ApexSQL Log-SQL误操作恢复工具
  10. RHEL6解决无法使用YUM源问题
  11. SLAM reference
  12. php ticks 调试应用
  13. thinkphp xml编码函数
  14. jQuery插件开发 格式与解析3之$.extend()用途
  15. centos6.5环境安装zookeeper-3.4.5
  16. Maven CXF wsdl2Java List<Xxx>生成ArrayOfXxx包装对象 解决方法
  17. SRP周记_20190418
  18. SSRS配置
  19. Hibernate不能实时获取MySQL数据库的更新
  20. JAR,WAR,EAR的使用与区别

热门文章

  1. [转] 从此不再惧怕URI编码:JavaScript及C# URI编码详解
  2. CF13C Sequence
  3. yii2.0 在save保存之前的操作(放在模型model文件内)
  4. 移动端 Touch 事件
  5. 2.spring:集合属性
  6. Java 和 .NET SHA1算法记录
  7. MongoDB的角色作用(1)
  8. Android杀死进程方法
  9. maven中的坐标和仓库
  10. 使用PLSQL客户端登录ORACLE时报ORA-12502和ORA-12545错误的解决方案