代码签名
什么是代码签名
代码签名是对可执行文件或脚本进行数字签名,用来确认软件的来源并保证在签名后未被修改或损坏的措施。和数字签名原理一样,只不过签名的数据是代码而已.数字签名使用非对称加密和哈希函数来确保数据的完整性,可以用于识别和验证签名者。
代码签名的好处
- 确保一段代码自签名后未被更改。系统甚至可以检测到最小的更改,无论是有意的(例如恶意攻击者)还是意外的(例如文件损坏时)。当代码签名完好无损时,系统可以确定代码与签名者的预期相符。
- 将代码标识为来自特定来源(开发人员或签名者)。代码签名包括明确指向特定作者的密码信息。
- 确定代码对于特定目的是否值得信赖。除此之外,开发人员可以使用代码签名来声明应用程序的更新版本应被系统视为与先前版本相同的应用程序。
苹果签名过程
证书和密钥
-
CSR文件CSR
文件
通常,在开发使用的机器上应该已经有一个开发者证书,一个公钥,以及一个私钥。 这些是代码签名机制的核心。像 SSL 一样,代码签名也依赖于采用 X.509 标准的公开密钥加密。开发者通过 Key Chain 生成 CertificateSigningRequest(证书请求文件) 文件,这个文件里面包含了开发者的个人信息和公钥,并且在申请时私钥保存在本地。
-
CER
文件
开发者将 CSR 文件上传至苹果网站提交给 Apple Worldwide Developer Relations Certification Authority(Apple WWDRCA)。Apple WWDRCA 会使用其根证书私钥签名生成了.cer
证书文件,这个证书里面包含了开发者的信息和公钥,以及数字签名。在 OS X 上,X.509 的基本组成部分(例如证书等)都是由一个叫Key chain(钥匙串访问)的工具来进行管理。当下载 CER 文件安装至钥匙串时,钥匙串会将这两个证书进行关联,要用一个证书设置代码签名,必须拥有私钥,所有证书的私钥都会被列在这里。 还有一种可以用来快速地显示出系统中能用来对代码进行签名的认证的方法,那就是利用用途广泛的命令行工具 security:
security find-identity -v -p codesigning
-
P12
文件
当 CER 安装到钥匙串中,开发者将其导出为.P12
格式的文件,这个文件中不仅包含了公钥信息,还有私钥信息,以及数字签名。
授权机制(Entitlements) 和 配置文件 (Provisioning)
苹果对 App 的 部分功能设定了权限开关,把这些权限开关统一称为 Entitlements(授权文件),并且对安装的设备(Device)做了限制,需要注册的设备才可以 安装,将AppId
、Device
、Entitlements
以及其他信息保存到了 Provisioning Profile(描述文件)文件中。
当开发者下载 .mobileprovision
文件后双击运行,Xcode 通常会将其存放在 ~/Library/MobileDevice/Provisioning Profiles/
目录中。开发者可以前往该目录或者安装 ProfilesManager.app
进行查看当前电脑下的描述文件。 可以通过下面命令查看下载后的描述文件信息:
security cms -D -i <mobileprovision文件路径>
通过查看后,我们可以发现 Provisioning Profile 文件其实是 plist 文件, 当然,Provisioning Profile文件也是经过服务器数字签名的,所以它是防篡改的。
codesign
苹果对 App 签名过程本身是由命令行工具 codesign
来完成的。通常,Xcode 会处理大多数代码签名任务,帮助管理代码签名身份,并将代码签名应用于构建和分发的应用程序。需要注意的是 Xcode 只允许在有限的选项中进行选择,这些选项都是既拥有公钥也拥有私钥的证书。当然了,开发者也可以使用 codesign 工具进行手动签名:
-
手动代码签名
codesign -s <身份> -v <代码路径>
-
检查代码签名
codesign -v <代码路径>
-
获取有关代码签名信息
codesign -d -r- <代码路径>
那么在签名过程中,codeSign 做了什么呢?
codesign 将 App 内的资源(包括可执行文件、资源、文件、嵌套代码(Framework)等)在进行一次数字签名,通过单向散列函数获得哈希值,并用开发者的私钥 M 对其进行加密,并将苹果服务器生成的数字证书一起保存至 App 内。在 App 内可能包含不同的数字签名:
- 如果代码是通用的,则每个切片(架构)的目标代码都是单独签名的。此签名存储在二进制文件 Mach-O 本身中。
- 应用程序包的各种数据组件(例如Info.plist文件,如果有的话)也被签名。这些签名存储在
_CodeSignature/CodeResources
捆绑包中调用的文件中。 - 嵌入在应用程序中的嵌套代码(例如Framework)本身是经过签名的,并且它们的签名也存储在
_CodeSignature/CodeResources
包中。
App 安装
苹果系统原本就持有 WWDRCA 的公钥A,系统通过公钥 A,对 App 内存放的苹果服务器签名过的数字证书进行验证,查看是否经过苹果官方许可,并对比 UUID 等信息,这里只验证安装行为是否正确。在通过证书内的开发者公钥对代码签名进行验证,这里验证代码的完整性。
钥匙串-系统-Apple WWDRCA
网友评论