美文网首页iOS常用
iOS 开发者证书

iOS 开发者证书

作者: NapoleonY | 来源:发表于2020-08-20 19:00 被阅读0次

    证书的申请流程

    App Id 申请

    一个 App Id 对应1个程序。在[iOS 开发者网站](https://developer.apple.com](https://link.jianshu.com/?t=https://developer.apple.com/) Certificates 中可以看到下图中的内容。点击 App IDs 中加号,填写 App ID,其中 Bundle ID 有 Explicit App ID 和 Wildcard App ID(通配符) 两种

    证书申请
    1. 本地生成“证书请求文件” CSR 文件
      • 钥匙串访问->证书助理->从证书颁发机构请求证书
      • 选择“存储到磁盘” 即可生成一个 .certSigningRequest 文件
    2. 选择证书类型
    3. 上传之前本地生成的 CSR 文件,就生成了对应的证书文件 .cer。
    授权文件申请 Provisioning Profile
    1. 选择授权文件类型
    2. 关联 App ID
    3. 选择关联的证书
    4. 选择授权的设备

    iOS 代码签名

    2008 年苹果发布 iOS 2.0时引入了强制代码签名(Mandatory Code Signing) 技术,为了能够严格控制设备上能够运行的代码,这为 iOS 设备的安全性和苹果的 AppStore 生态奠定了坚实的基础。

    0x01 签名的作用

    数字签名和手写签名类似,代表签名者对被签名数据的署名和认可,签名是对信息发送行为真实性的有效保障。iOS 代码签名的目的和好处如下

    安全性

    代码签名的首要任务是保证设备及系统的安全性,只有被苹果设备认可的证书签名的代码才能够被执行。iOS 系统内置了来自苹果的 CA 证书,系统自身的代码都是被苹果“签名”过的,而用户从 AppStore 下载的 App 也被苹果官方签名。签名机制可以有效防止来自外部的攻击,即能够避免非授权的恶意代码运行

    沙盒

    可以有效限制 App 的行为,这部分功能主要是由 Sandbox 机制来保证。但 Sandbox 的配置是绑定在签名中的,即 Entitlements 文件。如果 Entitlements 文件可以被任意修改,那么 Sandbox 就失去了意义。因此 Entitlements 文件也是强制签名保护的对象。

    垄断

    代码签名还给苹果带来了一个好处: App 分发的绝对控制权。

    0x02 什么是签名

    签名的本质是用于验证数据的合法性,确保被签名的数据来自特定的来源,并且未经篡改。它基于对称性加密和哈希算法。

    公钥加密算法(非对称加密)

    它在加密和解密时使用的是不同的密钥,具有这样的特征:

    • 有一对密钥 ab,满足 a ≠ b
    • 用密钥 a 加密的数据只能用 b 进行解密,a 自身无法解密,反之亦然
    • 只知道其中一个密钥,无法推导出另一个
    • 把其中一个可以公开的叫做公钥,另一个不能公开的叫做似钥



      最常见的公钥加密算法是 RSA 公钥加密算法,也是签名中普遍使用的算法

    哈希算法

    也叫散列或者摘要算法,对一段任意长度的数据,通过一定的映射和计算,得到一个固定长度的值,这个值就被称为这段数据的哈希值,给定一个哈希算法,它一定有如下特征:

    • 哈希值不同的两段数据绝对不同
    • 相同的数据计算出的哈希值绝对不同
    • 由于哈希值是固定长度,也就意味着哈希值的数量是有限的。而任意数据都可以计算出一个哈希值,计算哈希的过程,相当于无限集映射到有限集。因此哈希值相同,对应的原始数据不一定相同,如果不同,则称这两段数据存在哈希碰撞,实际应用中任务是小概率事件,优秀的哈希算法都是碰撞率极低的。
    • 哈希算法是单向算法,无法通过哈希值,计算出原始数据,这一点非常重要。
      常见的哈希算法有:md5、sha1、sha256等,其中 sha1 长度为 160bits,而 sha256 长度为 256bits,二者相比,sha256 的取值范围更大,因此碰撞和破解的概率更低,也就相对安全
    签名算法

    有了上面两种算法作为基础,就可以组建一个签名和验证签名的体系了,如图所示


    假如 A 要给 B 发送一段数据,先对其签名:
    • 计算 d 的哈希值 h,并使用自己的私钥 ah 进行加密,得到的密文 c 就是签名。
      得到签名后,将数据 d 和签名 c 通过某种方式发送给 B,此时 B 收到了数据 d’ 以及签名 c‘,需要验证这段数据是否被篡改,以及是否是 A 发送的
    • 计算 d‘ 的哈希值 h’,使用 A 的公钥 b 将签名 c‘ 解密,得到 h’‘,通过对比 h’‘h’ 是否一致,就可以知道数据的签名是否被篡改,如果哈希值是匹配的,能够说明这段数据一定是由 A 签名并发出的。
      常见的签名算法:
    • sha1WithRSAEncryption:先对数据计算 sha1 摘要,再对摘要进行 RSA 加密
    • sha256WithRSAEncryption
    • md5WithRSAEncryption
    证书

    上面例子中,任何需要接受 A 的消息的人都需要事先保存 A 的公钥。这样存在一个问题: B 不可能事先将所有来源的公钥提前保存。因此一般会把公钥当作签名的一部分岁数据一起分发,接收方不需要事先保存任何来源的公钥。

    这样就引入了一个新问题:如何知道数据中所携带的公钥是否是发送者自己的公钥?

    解决方案:可以把公钥和所有者信息保存在一个文件里,并让一个可信的第三者使用其私钥对这个文件进行签名,得到了一个签了名的公钥问价,这个文件叫做 证书。证书会作为签名的一部分,随着数据一起分发。

    数据签名中的证书本身也是一段数据(公钥+所有者信息)以及签名组成,但证书中的签名是简单签名,只有哈希值和签发者名称,没有签发者的证书,否则就会陷入无限的递归死循环了。

    此时我们还需要第三者的公钥验证这个证书的合法性。虽然需要多了验证第三者公钥这一步,但是这样,本地不再需要保存每个数据来源的公钥,只需要保存这个第三者的证书(公钥)即可,每个数据来源的证书都由这个可信的第三者进行签发,这个可信的第三者就被称为证书颁发机构(Certification Authority)简称 CA

    0x03 开发者证书

    iOS 设备并不能像 Android 那样任意安装 App,App 必须被 Apple 签名之后才能安装。而开发者开发 App 需要频繁修改代码,不可能每次都上传给 Apple 进行签名,因此需要一种不需要苹果签名就可以运行的机制。这个机制的实现方式是:

    • 开发者自己持有一套密钥和证书,可以自行对 App 进行签名
    • Apple 对开发者身份进行“背书”,让设备能够信任开发者自行签名的 App,这个“背书”方式的背后就是 Provisioning Profile

    获取开发者证书的两个步骤:

    生成 CSR 文件(Ceritificate Signing Request)

    在 Keychain 菜单栏选择“从证书颁发机构请求证书”



    这个操作会产生一个名为 CertificateSigningRequest.certSigningRequest 的签名请求文件,在生成这个文件之前,Keychain 已经自动生成了一对公、私钥
    CSR 文件的内容其实就是个人信息、公钥以及自签名(使用自己的私钥进行签名)。
    提交给 Apple 进行签名

    在苹果开发者网站,将 CSR 提交给 Apple 进行签名,Apple 会返回一个签好名的 证书文件,后缀名为 cer。双击将其导入 Keychain 中,Keychain 会自动把它与之前创建 CSR 时自动生成的密钥归为一组

    查看证书内容

    可以得到几个关键信息:

    1. 证书所有者: Apple 根据我们的账号信息自动生成
    2. 证书的签发者:前文中的 CA
    3. 证书的公钥信息:与之前生成的密钥文件及 CSR 完全一致

    现在应该可以理解证书与密钥的关系了,密钥中保存了私钥和公钥,私钥用于签名,而证书里面有且只有公钥,并且是被第三方 CA 认证公,用于解密和校验。

    一般我们说使用 证书 签名,实际是使用与证书所匹配的私钥进行 签名证书只是作为签名数据的一部分被嵌入到签名结构中。

    开发证书、发布证书

    开发者证书按用途分为 Development 证书和 Distribution 证书:

    • Developent 证书:用于开发及测试阶段使用的证书,用于设备安装开发阶段的 App 后对 App 的完整性进行校验,一般名称为 iPhone Developer: xxxxxxx。如果是多人协作的开发者账号,任意成员都可申请自己的 Developent 证书
    • Distribution 证书:用于提交 AppStore 的证书,一般命名为 iPhone Distribution: xxxxxxxxx,用于让 AppStore 校验提交的 App 的完整性,只有管理人员以上身份的开发者账号才可以申请,因此可以控制提交权限的范围,同时不能用于开发及调试。
    0x04 Entitlements & Provisioning Profile

    除了开发者证书,进行 iOS代码签名时还需要两个文件,它们是被签名内容的一部分

    Entitlements

    沙盒(Sandbox)技术时 iOS 安全体系中非常重要的一项技术,目的通过各种技术手段限制 App 的行为,比如可读写的路径、允许访问的硬件、允许使用的服务等,即使出现任意代码执行的漏洞,也无法影响到沙盒外的系统。
    通常说的Entitlements 文件就是 iOS 沙盒的配置文件,这个文件声明了 app 所需的权限,如果 app 中使用了某项沙盒限制的功能,但是没有声明对应的权限,可能运行到相关的代码时会直接 crash

    Provisioning Profile

    Provisioning Profile 在这里签到了一个对设备和开发者授权的作用,它将开发者账号、证书、 entitlements 文件以及设备进行了绑定。
    Xcode 8及后续版本默认情况下会自动帮我们管理 Provisioning Profile,自动下载的 Provisioning Profile 都被放在 ~/Library/MobileDevice/Provisioning\ Profiles/ 路径下,以 UUID 格式命名。


    由于这个文件时被苹果签过名的,所以我们没有办法伪造和修改这个文件。 Provisioning Profile 统一是由 Apple iPhone OS Provisioning Profile Signing 进行签名的,机构名称言简意赅。里面的内容关键的几项为:
    • DeveloperCertificates: 允许使用的开发者证书,是一个列表,一般包含生成这个 Provisioning Profile 文件时当前开发者账号下所有有效的 Development 证书
    • Entitlements:允许使用的权限列表,实际在 App 中使用的权限必须时这个列表的子集,否则安装时无法通过校验而失败
    • ProvisionedDevices:允许安装的设备列表,如果目标设备的 UUID 不在这个列表中,会安装失败。

    Provisioning Profile 会被内置在 App 中,置于App 根目录下的 embedded.mobileprovision 。安装 App 时如果签名校验通过,这个文件会自动被拷贝到 iOS 设备的 /Library/MobileDevice/Provisioning Profiles/ 路径下。由于该文件已被 Apple 官方签名,系统可以无条件信任它,并用它来校验 App 的签名、权限以及本机的 UUID 等是否满足来自官方的授权,这种方式,间接信任了使用开发者证书签名的 App,让 App 设备可以运行非苹果官方签名的 App。

    开发密钥 p12 文件

    每一个证书都可以生成一个 .p12 文件,这是个加密文件,只要知道密码就可以供给其他 Mac 设备使用。使设备不需要在苹果开发者网站重新申请开发证书。
    通过配置证书的电脑,在钥匙串访问中,右键证书->导出即可导出 p12 文件,安装到其他 Mac 上,其他 Mac 才可以使用 Provisioning Profi[图片上传中...(1178833-d16f85597dc10149.png-97ea38-1597921146793-0)]
    le 副本
    注意: .p12 文件一般是给别的电脑使用的

    参考

    1. ios-app证书配置、打包提交
    2. iOS 证书申请和使用详解
    3. 深度长文:细说iOS代码签名

    相关文章

      网友评论

        本文标题:iOS 开发者证书

        本文链接:https://www.haomeiwen.com/subject/xlyejktx.html