IOS签名机制详解

背景

在开发手Q需要真机调试的时候经常有同事抱怨签名报错的问题,一方面是手Q工程非常庞大、有很多Target每个都需要签名,另一方面IOS签名本身就非常繁琐复杂,其次,很多开发者对签名机制没有彻底掌握,导致出现问题浪费好多时间。所以花了一些时间仔细研究总结了一下IOS签名机制,推荐给大家,希望本文有助于开发者更好地理解IOS签名机制,提升开发效率。

苹果为什么要推出签名机制

苹果一直致力于打造一个健康的闭环生态圈,只有符合标准的App才能在平台上运行,所以推出一个准入认证机制,来保证App的质量和用户的安全。WindowsAndroid等开发平台上的流氓软件横行,我觉得主要一个原因还是平台缺少审核机制。

关键技术和基础原理

目前App主要通过四种途径在苹果平台上运行: 1.App Store 2.真机调试 3.In-House 企业内部分发,用企业证书签名后可直接运行 4.AD-Hoc相当于企业分发的限制版,限制安装设备数量

App Store是采用单层签名验证机制,后面三种情况使用的是双层签名验证机制,接下来从相对简单的单层签名验证机制开始,详细讲解两者的区别和具体实现过程。

单层签名验证

实现过程大致分为以下几步:

  1. 苹果官方生成一对公私钥,在 iOS 里内置一个公钥,私钥由苹果后台保存。
  2. 我们传 App 上 AppStore 时,苹果后台用私钥对 APP 数据进行签名。
  3. iOS 系统下载这个 APP 后,用内置的公钥验证这个签名,若签名正确,这个 APP 肯定是由苹果后台认证的,并且没有被修改过,就可以正常运行在IOS上,否则,不能运行。

从上图分析可以看出,签名验证机制的核心技术是数字签名。

数字签名

数字签名的主要作用防止数据被篡改、防止抵赖,数字签名是非对称密钥加密技术与数字摘要技术的应用。接下来讲解一下数字签名的实现过程:

实现过程大致分为以下几步:

  1. 首先用一种算法,算出原始数据的摘要。这种算法需要满足两个条件:若原始数据有任何变化,计算出来的摘要值都会变化。摘要要够短。这里最常用的算法是MD5。
  2. 生成一份非对称加密的公钥和私钥,私钥我自己拿着,公钥公布出去。
  3. 用私钥加密这个摘要,得到一份加密后的数据,称为原始数据的签名。
  4. 摘要和原始数据一起发送给用户。
  5. 用户收到数据和签名后,用公钥解密得到摘要。同时用户用同样的算法计算原始数据的摘要,对比这里计算出来的摘要和用公钥解密签名得到的摘要是否相等,若相等则表示这份数据中途没有被篡改过,因为如果篡改过,摘要会变化。 从上述分析可以看出,数字签名技术主要依赖加密技术和摘要算法,接下来简单介绍一下非对称加密技术。

非对称加密

非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

非对称密码体制的特点:算法强度复杂、安全性依赖于算法与密钥但是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。

了解更多前往 RSA 算法原理(一)RSA 算法原理(二)

双层签名验证

在很多种情况下App不需要传到苹果后台认证和审核,能直接在平台上运行,但是苹果又需要对这种情况进行监管和控制,比如说:真机调试、企业证书签名等。为了解决这个问题,因此推出了双层签名认证机制。

大致流程分为以下几步:

  • 第1步,对应的是 keychain 里的 “从证书颁发机构请求证书”,这里就本地生成了一对公私钥,保存的 CertificateSigningRequest 就是公钥,私钥保存在本地电脑里。
  • 第2步,苹果自身实现。
  • 第3步,对应把 CertificateSigningRequest 传到苹果后台生成证书,并下载到本地。这时本地有两个证书,一个是第 1 步生成的,一个是这里下载回来的,keychain 会把这两个证书关联起来,因为他们公私钥是对应的,在XCode选择下载回来的证书时,实际上会找到 keychain 里对应的私钥去签名。这里私钥只有生成它的这台 Mac 有,如果别的 Mac 也要编译签名这个 App 怎么办?答案是把私钥导出给其他 Mac 用,在 keychain 里导出私钥,就会存成 .p12 文件,其他 Mac 打开后就导入了这个私钥。
  • 第4步,都是在苹果网站上操作,配置 AppID / 权限 / 设备等,最后下载 Provisioning Profile 文件。
  • 第5步,XCode 会通过第 3 步下载回来的证书(存着公钥),在本地找到对应的私钥(第一步生成的),用本地私钥去签名 App,并把 Provisioning Profile 文件命名为 embedded.mobileprovision 一起打包进去。这里对 App 的签名数据保存分两部分,Mach-O 可执行文件会把签名直接写入这个文件里,其他资源文件则会保存在 _CodeSignature 目录下。
  • 第6步,在安装时,iOS 系统取得证书,通过系统内置的公钥 A,去验证 embedded.mobileprovision 的数字签名是否正确,里面的证书签名也会再验一遍。
  • 第7步,确保了 embedded.mobileprovision 里的数据都是苹果授权以后,就可以取出里面的数据,做各种验证,包括用公钥 L 验证APP签名,验证设备 ID 是否在 ID 列表上,AppID 是否对应得上,权限开关是否跟 APP 里的 Entitlements 对应等。

名词解释 证书:公钥+签名信息 Code Signing Identity:证书+私钥 .p12文件:导出的私钥就是p12文件格式 Entitlements:授权机制决定了哪些系统资源在什么情况下允许被一个应用使用。简单的说它就是一个沙盒的配置列表,上面列出了哪些行为被允许,哪些会被拒绝。在xcodeCapabilities中列举的功能都是需要配置授权的。 Provisioning Profile:证书+设备IDs+AppID+Entitlements+签名信息

小结

提交App Store的应用就是采用单层签名验证,只需要苹果自身的公私秘钥就能完成。而企业签名、真机调试等情形,不仅需要苹果参与签名,而且需要开发者自身参与签名,因此称之为双层签名验证。

参考文献

bang’s blog 代码签名探析

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏青玉伏案

TCP/IP协议族(三) 数字签名与HTTPS详解

前面几篇博客聊了HTTP的相关东西,今天就来聊一聊HTTPS的东西。因为HTTP协议本身存在着明文传输、不能很好的验证通信方的身份和无法验证报文的完整性等一些安...

2047
来自专栏IMWeb前端团队

HTTPS科普扫盲帖

本文作者:IMWeb 陈映平 原文出处:IMWeb社区 未经同意,禁止转载 为什么需要https HTTP是明文传输的,也就意味着,介于发送端、接收端...

8448
来自专栏java一日一条

最详细的 HTTPS 科普扫盲帖

HTTP是明文传输的,也就意味着,介于发送端、接收端中间的任意节点都可以知道你们传输的内容是什么。这些节点可能是路由器、代理等。

513
来自专栏IT派

HTTPS 到底加密了什么?

关于 HTTP 和 HTTPS 这个老生常谈的话题,我们之前已经写过很多文章了,比如这篇《从HTTP到HTTPS再到HSTS》,详细讲解了 HTTP 和 HTT...

611
来自专栏派森公园

HTTPS是如何工作的

大家在浏览网页的时候一定有这样的体验,有一些网站在网址那里会显示一个绿色的挂锁,并且网址中“https”相关的字样也是绿色的,聪明的朋友肯定会问,这些颜色和符号...

754
来自专栏安智客

Key attestation的几个关键点!

Key attestation就是密钥认证,之前介绍过: Key attestation-Google的密钥认证 下图是Google Android密钥认证的架...

4287
来自专栏贾老师の博客

数字证书与安全

1263
来自专栏枕边书

再谈加密-RSA非对称加密的理解和使用

前言 随着互联网越来越渗透入我们生活的方方面面,各种私密信息在网络中传播,为了保证信息的真实可靠,在我们对其安全性的要求也越来越高,对此,加密是一个永远不过时的...

2289
来自专栏信安之路

HTTPS攻击原理与防御

超文本传输安全协议( HTTPS )是一种通过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP 进行通信,但利用 SSL/TLS 来加密数据包。 H...

660
来自专栏菜鸟计划

HTTPS科普(转) 为什么需要https

为什么需要https HTTP是明文传输的,也就意味着,介于发送端、接收端中间的任意节点都可以知道你们传输的内容是什么。这些节点可能是路由器、代理等。 举个最常...

3415

扫码关注云+社区