• Apple App签名机制


    概览

    • 数字签名
    • 签名机制与验证过程
    • 操作流程

    数字签名

      摘要算法

    1. 将任意长度文本通过一个算法得到一个固定长度的文本。 
    2. 源文本不同,计算结果必然不同 
    3. 无法从结果反推源

      例如,MD5和SHA算法

      非对称加密

    1. 即加密密钥与解密密钥不同,且成对出现 
    2. 对外公开的称为公钥,这对密钥生成者才拥有的称为私钥 
    3. 通过私钥加密的密文只能通过公钥解密,反之亦然 

      例如,RSA算法,非对称加密加解密比较耗时,实际使用中,往往与对称加密和摘要算法结合使用

    数字签名的作用是我对某一份数据打了个标记,表示我认可了这份数据(签了个名),然后我发送给其他人,其他人可以知道这份数据是经过我认证的,数据没有被篡改过。

    哪怎么做呢?

    1. 生成一份非对称加密的公钥和私钥,私钥自己拿着,公钥发布出去。
    2. 用一种算法,算出原始数据的摘要。常用的算法是MD5。

    对一份数据,算出摘要之后,用私钥加密这个摘要,得到一份加密后的数据,称为原始数据的签名。把它跟原始数据一起发送给用户。

    用户收到数据和签名后,用公钥解密得到摘要,同时用户用同样的算法计算原始数据的摘要,比对这里计算出来的摘要和公钥解密签名得到的摘要是否相等,若相等则表示这份数据中途没有被篡改过,因为如果有篡改,摘要会变化。

    签名机制与验证过程

      最简单的签名  

    苹果官方生成一对公私钥,在iOS里内置一个公钥,私钥由苹果后台保存,我们传App上AppStore时,苹果后台用私钥对App数据进行签名,iOS系统下载这个App后,用公钥验证这个签名,若签名正确,这个App肯定由苹果后台认证的,并且没有被修改过,也就达到了苹果的需求:保证安装的每一个App都是经过苹果认证允许的。

     
    但是实际上开发APP还有其他渠道来安装。
    • 开发App时可以直接把开发中的应用安装进手机调试;
    • In-House企业内部分发,可以直接安装企业证书签名后的App;
    • AD-Hoc相当于企业分发的限制版,限制安装设备数量。
     

    iOS的双层代码签名

      安装包不需要传到苹果服务器,经过苹果认证后,可以直接安装到手机上。

    生成签名

    1. 在Mac开发机器生成一对公私钥,这里称公钥L,私钥L;
    2. 把公钥L上传到苹果后台,用苹果后台里的私钥A去签名公钥L。得到一份数据包含了公钥L以及其签名,把这份数据称为证书;
    3. 编译完一个 APP 后,用本地的私钥 M(今后你导出的P12) 对这个 APP 进行签名,同时把第三步得到的证书一起打包进 APP 里;

    认证过程

    1. 在安装时,iOS 系统取得证书,通过系统内置的公钥 A,去验证证书的数字签名是否正确;
    2. 验证证书后确保了公钥 L 是苹果认证过的,再用公钥 L 去验证 APP 的签名。

    这里就间接验证了这个 APP 安装行为是否经过苹果官方允许。

    但是这种签名方式并不能解决应用滥用的问题,所以苹果又加了两个限制.第一限制在苹果后台注册过的设备才可以安装.第二限制签名只能针对某一个具体的APP.并且苹果还想控制App里面的iCloud/PUSH/后台运行/调试器附加这些权限,所以苹果把这些权限开关统一称为Entitlements(授权文件).并将这个文件放在了一个叫做Provisioning Profile(描述文件)文件中。

    描述文件

    描述文件是在AppleDevelop网站创建,描述文件里面就是 可以安装的设备有哪些,APP的ID是什么,权限是些什么!

    加上这个东西后这个签名机制是什么样呢?
     

     

    生成签名

    1. 在Mac开发机器生成一对公私钥,这里称公钥L,私钥L;
    2. 把公钥L上传到苹果后台,用苹果后台里的私钥A去签名公钥L。得到一份数据包含了公钥L以及其签名,把这份数据称为证书,和一份描述文件
    3. 编译完一个 APP 后,用本地的私钥M对这个APP进行签名,同时把从苹果服务器得到的 Provisioning Profile 文件打包进APP里,文件名为embedded.mobileprovision

    认证过程

    1. 在安装时,iOS 系统取得证书,通过系统内置的公钥 A,去验证证书的数字签名是否正确;
    2. 通过系统内置的公钥 A,解密拿到描述文件,查看里面的设备列表时候包含当前设备;
    3. 验证证书后确保了公钥 L 是苹果认证过的,再用公钥 L 去验证 APP 的签名;
    4. 验证描述文件里的AppID是否与当前App的AppID一致,App申请的功能时候与描述文件一致;

    操作流程

    • 第 1 步对应的是 keychain 里的 “从证书颁发机构请求证书”,这里就本地生成了一对公私钥,保存的 CertificateSigningRequest 里面就包含公钥,私钥保存在本地电脑里.
    • 第 2 步向苹果申请对应把 CSR 传到苹果后台生成证书.
    • 第 3 步证书下载到本地.这时本地有两个证书.一个是第 1 步生成的私钥,一个是这里下载回来的证书,keychain 会把这两个证书关联起来,因为他们公私钥是对应的,在XCode选择下载回来的证书时,实际上会找到 keychain 里对应的私钥去签名.这里私钥只有生成它的这台 Mac 有,如果别的 Mac 也要编译签名这个 App 怎么办?答案是把私钥导出给其他 Mac 用,在 keychain 里导出私钥,就会存成 .p12 文件,其他 Mac 打开后就导入了这个私钥.

    • 第 4 步都是在苹果网站上操作,配置 AppID / 权限 / 设备等,最后下载 Provisioning Profile 文件。
    • 第 5 步 XCode 会通过第 3 步下载回来的证书(存着公钥),在本地找到对应的私钥(第一步生成的),用本地私钥去签名 App,并把 Provisioning Profile 文件命名为 embedded.mobileprovision 一起打包进去。所以任何本地调试的APP,都会有一个embedded.mobileprovision(描述文件)从App Store下载的没有.

    说在最后

    AppStore的签名验证方式有些不一样,前面我们说到最简单的签名方式,苹果在后台直接用私钥签名App就可以了,实际上苹果确实是这样做的,如果去下载一个AppStore的安装包,会发现它里面是没有embedded.mobileprovision文件的,也就是它安装和启动的流程是不依赖这个文件,验证流程也就跟上述几种类型不一样了。

    据猜测,因为上传到AppStore的包苹果会重新对内容加密,原来的本地私钥签名就没有用了,需要重新签名,从AppStore下载的包苹果也并不打算控制它的有效期,不需要内置一个embedded.mobileprovision去做校验,直接在苹果用后台的私钥重新签名,iOS安装时用本地公钥验证App签名就可以了。

    那为什么发布AppStore的包还是要跟开发版一样搞各种证书和Provisioning Profile?猜测因为苹果想做统一管理,Provisioning Profile里包含一些权限控制,AppID 的检验等,苹果不想在上传AppStore 包时重新用另一种协议做一遍这些验证,就不如统一把这部分放在 Provisioning Profile里,上传AppStore时只要用同样的流程验证这个 Provisioning Profile是否合法就可以了。

    所以 App 上传到AppStore后,就跟你的 证书 / Provisioning Profile 都没有关系了,无论他们是否过期或被废除,都不会影响AppStore 上的安装包。

  • 相关阅读:
    压测 正则 性能分析
    时间复杂度 根号n
    务端如何防止重复支付 架构文摘 2021-05-02
    工具大于约定和文档
    千亿级公司低代码平台的测试体系介绍
    疑惑 题解
    计算几何相关总结
    树 题解
    矩阵加速相关总结
    loj6274 数字 题解
  • 原文地址:https://www.cnblogs.com/Lanht/p/11152199.html
Copyright © 2020-2023  润新知