(八)代码签名 CodeSigning 的原理与过程

作者:kim

时间:Apr 29, 2015

版权:非商用,自由转载,请保留原文地址

 

 

在介绍真机运行调试之前,我们先介绍代码签名的概念。代码签名是 App 之所以能够在真机上运行的基础!每个 iOS 开发者都必须跨过的坑!

 

1. 代码签名 Code Signing 也叫 App 签名,它是依靠 iOS 证书来进行的,它保证了 App 的合法性、完整性、真实性以及一致性(未被修改)。

 

2. 代码签名的核心是:证书、公钥、私钥。依赖于 X.509标准 与 公开密钥加密。

 

3. 在 Xcode 中设置代码签名非常简单,只需要设置 Targets -> Build Settings -> Code Signing Identity 设置好签名信息。
假如是正式发布的话,推荐手动设置签名证书!

 

7FA82D28-063A-40B1-8851-753F9FAE6040

 

4. 签名过程,在底层是由命令行工具 codesign 来完成的!当 Xcode 编译一个应用程序,在这个应用构建完成后就会自动调用 codesign 命令来进行签名!

 

5. 为了试验签名,我们先制作一个假的应用文件 apptest.app 做测试用。

 

61C6F48A-0388-4D70-A070-31C1F7077690

 

6. 公钥和私钥都完整可用的证书,才可以用来对代码进行签名,使用 security 命令,可以查看系统中的这类证书。这里需要记下 identity 的全称供后续使用。
$ security find-identity -v -p codesigning

 

46ABADAF-51BD-4FF1-8A24-D958AC2F27A7

 

7. 通过 codesign 命令使用上面的 identity ,对文件进行签名,期间需要授权允许使用用户本地的私钥。

 

7B299A80-C1FE-43AB-8EAF-24D60765EB85

 

8. 查看下已被签名的应用的信息。

注意,假如是一个正常的程序包,那么 Format 那里应该显示类似 “bundle with Mach-O thin (arm64)” 的信息。

 

AA966344-C361-47FA-873E-01FADC7C70BC

 

9. 检查一下当前的签名是否完美,即未被破坏。no news is good news!
$ codesign —verify apptest.app

 

10A1F858-284E-46CE-866E-E0346D8F1596

 

10. 尝试破坏一下签名,再验证,果然发现问题了!

 

D0B2474D-FAB7-4BFE-9E6D-93E31045F95B

 

11. 在实际对 App Bundle 的打包中,签名过程会在程序包中新建一个 _CodeSignature/CodeResources 的 plist 格式的文件,这个文件存储了被签名的程序包中所有资源文件的签名!

 

——————————————————————————–

 

12. 代码签名的验证主要是通过配置文件 Provisioning Profile(PP文件)与个人私钥 Private Key 共同完成。
(实际上,这个验证是通过 PP 文件里面的证书中的个人公钥 Public Key ,以及个人私钥 Private Key 共同完成的。)

 

13. 还记得我们在请求 Certificate 的时候,生成的 CSR 文件吗?这实际上是一个公钥/私钥对。私钥用于对代码进行签名,公钥用于验证。
我们可以在 Keychain 看到证书的公钥信息,以及与之配对的个人私钥(专用密钥)。

 

8237CE9F-57FF-4705-A445-8C54D1D581D5

 

14. 假如上面的私钥被删除,或者没了,那么就不能对代码进行签名,也就无法使用这个证书了。假如私钥被别人获取了,别人更可以“代替”你来发布 App 了!因此一定要保存好自己的私钥,最好是导出来保存在安全地方!

 

BDBD51D3-2DDB-4648-B617-4C3645D922FB

 

15. 选择 ”个人信息交换(.p12)” 文件格式,导出 .p12 文件!
由于 p12 文件包含个人信息,所以必须要密码。

 

F522B666-54BB-4BF9-BA38-70E3B52B2D78

 

78CA9B38-B563-4C18-95E6-26397731E382

 

16. 如果选择 “证书(.cer)” 文件格式,则导出证书文件本身!(也可以从 Apple Developer Member Center 下载)

 

433663E7-3D59-4D9A-82C9-31C016CFBBE9

 

17. 这样,如果想和别人或者其它设备共享证书时,只要把 p12 文件传给他,然后他就可以使用证书里面的私钥对代码进行签名了。

 

0AC81221-B68E-4B71-B3A2-1DA332B2EFAC

 

 

18. 代码签名:对指定信息使用哈希 Hash 算法,得到固定长度的信息摘要 Signature,然后再使用私钥 Private Key 对摘要进行加密,就得到了数字签名。

 

 

19. 代码签名的验证过程分两步:

 

第一步,验证证书本身的可信性与完整性:
1)在 iOS 系统以及其它 Mac 设备内部,都拥有苹果的根证书 AppleWWDRCA.cer,里面包含了 Apple 的公钥。
2)用 Apple 的公钥对证书(.cer)中包含的数字签名进行解密,如果成功得到(经过 Apple 使用私钥加密过的)信息摘要 Signature1,则说明了证书的可信性。
3)然后对证书内容使用证书声明的哈希算法,计算出一个信息摘要 Signature2。
4)如果 Signature1 == Signature2,则说了明证书的完整性。

 

第二步,验证代码的可信性与完整性:
1)在证书可信的前提下,成功提取出用户的真实公钥 Public Key。这个公钥就可以用于检验代码签名,或者用于加密通信。
2)用真实的用户公钥对 CodeSignature 里面所有代码/资源签名进行解密,得到一系列信息摘要 Signature-a1、Signature-b1、Signature-c1 etc.
3)假如所有信息摘要都正确被机密出来,则表明代码、资源文件是可信的,是完整的,能够合法地在该设备上运行。

 

 

Posted in iOS, Training | Tagged , , , , , , , , | Leave a comment