iOS APP签名机制

证书介绍

非对称加密

一般咱们证书里边的签名都是根据非对称加密算法完成的。 非对称加密有两份密钥,分别是公钥和私钥,用公钥加密的数据,要用私钥才干解密,用私钥加密的数据,要用公钥才干解密。

首要的算法: RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)。

简单说一下常用的非对称加密算法 RSA 的数学原理,理解数学原理,咱们就可以理解非对称加密是怎样完成的,为什么会是安全的:

  1. 选两个质数 p 和 q,相乘得出一个大整数n,例如 p = 61,q = 53,n = pq = 3233
  2. 选 1-n 间的随意一个质数e,例如 e = 17
  3. 经过一系列数学公式,算出一个数字 d,满意: a.经过 n 和 e 这两个数据一组数据进行数学运算后,可以经过 n 和 d 去反解运算,反过来也可以。 b.假如只知道 n 和 e,要推导出 d,需求知道 p 和 q,也便是要需求把 n 因数分解。 上述的 (n,e) 这两个数据在一同便是公钥,(n,d) 这两个数据便是私钥,满意用私钥加密,公钥解密,或反过来公钥加密,私钥解密,也满意在只露出公钥 (只知道 n 和 e)的情况下,要推导出私钥 (n,d),需求把大整数 n 因数分解。现在因数分解只能靠暴力穷举,而 n 数字越大,越难以用穷举计算出因数 p 和 q,也就越安全,当 n 大到二进制 1024 位或 2048 位时,以现在技术要破解简直不或许,所以十分安全。

RSA算法原理参阅: www.ruanyifeng.com/blog/2013/0…

非对称加密算法的特性:

  • 关于一个私钥,有且只需一个与之对应的公钥。生成者担任生成私钥和公钥,并保存私钥,揭露公钥
  • 公钥是揭露的,但不或许经过公钥反推出私钥,或者说极难反推,只能穷举,所以只需密钥足够长度,要经过穷举而得到私钥,简直是不或许的
  • 经过私钥加密的密文只能经过公钥解密,公钥加密的密文只需经过私钥解密

摘要算法

摘要算法是指,可以将恣意长度的文本,经过一个算法,得到一个固定长度的文本。 摘要算法具有以下重要特性:

  • 只需源文本不同,计算得到的成果,必然不同
  • 无法从成果反推出源 典型的摘要算法,比方MD5和SHA。

数字签名

数字签名运用了非对称加密和摘要算法,一般用于数据接收方(一般指客户端)验证数据发送发方(一般只指代服务器)发送的数据是否合法(是否经过第三方篡改)。

举个比如,A有一段文本要发给B,A为了避免文本在半途被歹意篡改。A找来C,C将文本内容经过摘要算法,得到摘要,再用C自己私钥对摘要加密得到密文,A将原文、密文一并发给B。接收方B收到数据今后用C的公钥(提前固化在体系中了)对密文进行解密,将文本用相同的算法得到摘要,两个摘要进行对比,假如相等那么一切正常,否则视为接收数据视为无效。

iOS APP签名机制

数字签名可以快速验证文本的完整性和合法性,已广泛运用于各个领域。

数字证书

数字证书便是经过数字签名完成的数字化的证书。苹果公司可以签发跟苹果公司有关的证书。

这儿签发组织都称为CA(Certificate Authority)。

苹果开发者账号与证书对应联系: 账号类型价格可以发布AppStore?支持装置设备数量恳求条件证书类型个人账号99可以100无约束Development,AdHoc,AppStore公司账号99可以100无约束Development, Ad Hoc, App Store公司账号99可以100DUNS编码Development, Ad Hoc, App Store企业账号299不可以无约束DUNS编码Development,AdHoc,InHouse教育账号299不可以无约束DUNS编码Development, Ad Hoc, In House教育账号0可以100教育组织Development, Ad Hoc, App Store 各个证书运用阐明:

  1. Development:开发 App 时可以直接把开发中的运用装置进手机进行调试。
  2. In House: 企业内部分发,可以直接装置企业证书签名后的 APP。
  3. Ad Hoc:相当于企业分发的约束版,约束装置设备数量,较少用。
  4. AppStore:上传运用商铺下载装置 证书恳求进程 咱们需求经过钥匙串生成一个CertificateSigningRequest.certSigningRequest文件来提交到苹果MC(Member Center)中,然后获取苹果证书。

certSigningRequest文件生成进程如下图:

iOS APP签名机制

运用openssl解析文件中的内容如下图:

iOS APP签名机制

certSigningRequest文件中包含信息:

  1. 恳求者信息,此信息是用恳求者的私钥加密的
  2. 恳求者公钥,此信息是恳求者运用的私钥对应的公钥
  3. 摘要算法(sha256)和公钥加密算法(rsa)

经过一系列在苹果开发者后台的操作后,得到苹果证书。 开发者证书比如如图:

iOS APP签名机制

APP签名原理

苹果的需求

  1. APP装置保证是开发者提交的代码而不会被半途歹意修正。
  2. 苹果想要对装置的App有操控权,包含
  3. 经过苹果允许才干够这样装置。
  4. 不能被滥用导致非开发app也能被装置。
  5. 装置包不需求上传到App Store, 也可以直接装置到手机上.
  6. 开发APP时直接真机调试装置
  7. 企业内部分发的途径,企业证书签名的APP也是需求顺畅装置的

签名原理

这儿以开发包为例,讲解下原理。 苹果这儿运用的方案是双层签名,流程图:

iOS APP签名机制

流程阐明:

  1. 在你的 Mac 开发机器生成一对公私钥,这儿称为公钥L,私钥L。L:Local
  2. 苹果自己有固定的一对公私钥,私钥在苹果后台,公钥在每个 iOS 设备上。这儿称为公钥A,私钥A。A:Apple
  3. 把公钥 L 传到苹果后台,用苹果后台里的私钥 A 去签名公钥 L。得到一份数据包含了公钥 L 以及其签名,把这份数据称为证书。
  4. 在苹果后台恳求 AppID,装备好设备 ID 列表和 APP 可运用的权限,再加上第③步的证书,组成的数据用私钥 A 签名,把数据和签名一同组成一个 Provisioning Profile 文件,下载到本地 Mac 开发机。
  5. 在开发时,编译完一个 APP 后,用本地的私钥 L 对这个 APP 进行签名,一同把第④步得到的 Provisioning Profile 文件打包进 APP 里,文件名为 embedded.mobileprovision,把 APP 装置到手机上。
  6. 在装置时,iOS 体系取得证书,经过体系内置的公钥 A,去验证 embedded.mobileprovision 的数字签名是否正确,里边的证书签名也会再验一遍。
  7. 保证了 embedded.mobileprovision 里的数据都是苹果授权今后,就可以取出里边的数据,做各种验证,包含用公钥 L 验证APP签名,验证设备 ID 是否在 ID 列表上,AppID 是否对应得上,权限开关是否跟 APP 里的 Entitlements 对应等。

上面的过程对应到咱们平常具体的操作和概念是这样的:

  1. 第 1 步对应的是 keychain 里的 “从证书颁布组织恳求证书”,这儿就本地生成了一对公私钥,保存的 CertificateSigningRequest 便是公钥,私钥保存在本地电脑里。
  2. 第 2 步苹果处理,不用管。
  3. 第 3 步对应把 CertificateSigningRequest 传到苹果后台生成证书,并下载到本地。这时本地有两个证书,一个是第 1 步生成的,一个是苹果后台下载回来的,keychain 会把这两个证书关联起来,因为他们公私钥是对应的,在XCode挑选下载回来的证书时,实践上会找到 keychain 里对应的私钥去签名。这儿私钥只需生成它的这台 Mac 有,假如别的 Mac 也要编译签名这个 App 怎样办?答案是把私钥导出给其他 Mac 用,在 keychain 里导出私钥,就会存成 .p12 文件,其他 Mac 打开后就导入了这个私钥。
  4. 第 4 步都是在苹果网站上操作,装备 AppID / 权限 / 设备等,最终下载 Provisioning Profile 文件。
  5. 第 5 步 XCode 会经过第 3 步下载回来的证书(存着公钥),在本地找到对应的私钥(第一步生成的),用本地私钥去签名 App,并把 Provisioning Profile 文件命名为 embedded.mobileprovision 一同打包进去。这儿对 App 的签名数据保存分两部分,Mach-O 可执行文件会把签名直接写入这个文件里,其他资源文件则会保存在 _CodeSignature 目录下。 第 6 – 7 步的打包和验证都是 Xcode 和 iOS 体系主动做的事。

再总结一下这些概念:

  1. 证书:内容是公钥或私钥,由其他组织对其签名组成的数据包。

  2. Entitlements:包含了 App 权限开关列表。

  3. CertificateSigningRequest:本地公钥。

  4. p12:本地私钥,可以导入到其他电脑。

  5. Provisioning Profile:包含了 证书 / Entitlements 等数据,并由苹果后台私钥签名的数据包。

  6. mobileprovision:从苹果后台下载下来的Provisioning Profile描绘文件

其他发布方法

前面以开发包为比如说了签名和验证的流程,另外两种方法 In-House 企业签名和 AD-Hoc 流程也是差不多的,只是企业签名不约束装置的设备数,另外需求用户在 iOS 体系设置上手动点击信赖这个企业才干经过验证。

而 AppStore 的签名验证方法有些不相同,苹果在后台直接用私钥签名 App 就可以了,假如去下载一个 AppStore 的装置包,会发现它里边是没有 embedded.mobileprovision 文件的,也便是它装置和发动的流程是不依赖这个文件,验证流程也就跟上述几种类型不相同。

那为什么发布 AppStore 的包仍是要跟开发版相同搞各种证书和 Provisioning Profile? 猜测因为苹果想做一致管理,Provisioning Profile 里包含一些权限操控,AppID 的检验等,苹果不想在上传 AppStore 包时从头用另一种协议做一遍这些验证,就不如一致把这部分放在 Provisioning Profile 里,上传 AppStore 时只需用相同的流程验证这个 Provisioning Profile 是否合法就可以了。 所以 App 上传到 AppStore 后,就跟你的 证书 / Provisioning Profile 都没有联系了,不管他们是否过期或被废弃,都不会影响 AppStore 上的装置包。

重签技术

运用场景:

  1. 证书过期或失效,不需求从头打包,直接运用新证书重签可以运用。
  2. App Store包运用企业证书重签,可以用于企业分发 企业证书签名因为约束少,在国内被广泛用于测验和盗版,fir.im / 蒲公英等测验平台都是经过企业证书分发,国内一些商场像 PP 帮手,爱思帮手,一部分装置手法也是经过企业证书重签名。经过企业证书签名装置的 App,发动时都会验证证书的有效期,并且不定期恳求苹果服务器看证书是否被撤消,若已过期或被撤消,就会无法发动 App。关于这种帮手的盗版装置手法,苹果想冲击只能一个个撤消企业证书,并没有太好的办法。

准备材料:

  1. 需求重签的ipa包
  2. 证书
  3. 描绘文件
  4. 非本机证书供给p12文件

IPA文件结构:

_CodeSignature:文件的hash列表。里边有一个文件 CodeResources 很重要,它是一个plist文件,包含一切文件及其对应的hash值。这个特点列表只需一项 files,这是一个字典,键是文件名,值一般是 Base64 格式的散列值。它的作用是用来判别一个运用程序是否完好无缺,可以避免半途修正或损坏资源文件。

iOS APP签名机制

Info.plist :存储运用的相关装备、Bundle identifier 和 Executable file 可执行文件名等信息 可执行文件:Info.plist 中 Executable file 记载的名字所对应的文件 Frameworks:当前运用运用的三方 Framework 或 Swift 动态库 PlugIns:当前运用运用的 Extension Watch:手表一同运用的运用 资源文件:包含图片资源文件、装备文件、视频/音频,以及一些与本地化相关的文件。

重签过程:

重签需求运用Xcode的指令 security 和 codesign 重签ipa文件。

  1. 增加p12证书
# Import items into a keychain.
$ security import inputfile [-k keychain] [-t type] [-f format] [-w] [-P passphrase] [options…]
$ security import /Users/htc/Desktop/distest.p12 -P '123456'
  1. 解压ipa包
$ unzip yourApp.ipa
# 查找 .app目录,删去体系临时文件
$ rm -rf ./Payload/yourAppName.app/.DS_Store
  1. 修正内容 修正Payload/yourName.app中的icon图标、Info.plist文件的信息等,如有需求也可以更改比方版本号,运用称号等。
  2. 删去之前的签名 _CodeSignature
$ rm -rf ./Payload/yourAppName.app/_CodeSignature
  1. 用包里的描绘文件生成entitlements.plist文件
$ security cms -D -i "xxx.mobileprovision"
可以用管道指令 > 保存成 plist 文件:
$ security cms -D -i embedded.mobileprovision > entitlement_full.plist
假如只保留 Entitlements 特点内容,则可以运用PlistBuddy指令,咱们重签只需求 Entitlements 特点:
$ /usr/libexec/PlistBuddy -x -c \'Print:Entitlements\' entitlement_full.plist > entitlement.plist
  1. 替换描绘文件 把新的描绘文件仿制替换到解压后的目录中,这个需求看自己需求,旧包的描绘权限与新证书的权限,是需求那些,上一过程中 Entitlements 便是在重签时还可以在指定。
$ cp ./embedded.mobileprovision ./Payload/yourAppName.app/embedded.mobileprovision
假如需求查看体系中已经保存的描绘文件:~/Library/MobileDevice/Provisioning\ Profiles/
  1. 给 MachO 文件增加执行权限
chmod +x ./Payload/yourAppName.app/yourAppName
  1. 获取证书内容
$ security find-identity -p codesigning -v

输出:本机一切可用证书列表 9. 从头签名 先重签名framework和dylib(不重签的话,就删去无法签名的插件文件: Framework、PlugIns 文件夹、Watch 文件夹)

$ /usr/bin/codesign --force --sign "iPhone Distribution:xxxxx" /Payload/XX.app/Frameworks/xxx.framework
再签名.app:
$ /usr/bin/codesign -f -s "iPhone Distribution:xxxxx"  --entitlements entitlements.plist ./Desktop/Payload/yourAppName.app
重签成功后提示:
./Payload/yourAppName.app: replacing existing signature.
  1. 紧缩Payload 生成最终 .ipa 文件
$ zip -ry ABC.ipa Payload

其他东西运用:

fastlane: docs.fastlane.tools/actions/#co…

图形化东西:

dantheman827.github.io/ios-app-sig… github.com/maciekish/i…

参阅资料

developer.apple.com/library/arc… developer.apple.com/library/arc… segmentfault.com/a/119000000… blog.cnbang.net/tech/3386/ ihtcboy.com/2019/07/30/…