目录
签名逻辑
iOS的签名需要用到两对儿公私钥,一对儿由苹果公司提供,公钥内置在iPhone设备内,私钥在苹果后台。另一对儿由开发者提供,公钥最终会被签名成证书,私钥存储在开发者的Mac电脑内,通过xcode编译APP时会对APP进行签名,安装到手机时会进行验签,从而达到对安装包的管控。
详细内容请参阅上篇博客iOS签名原理
当我们的项目编译完成后,在Products文件夹内会看到编译好的.app格式的包xxx.app,对其右键显示包内容,我们看到文件夹内有各种资源文件、Framworks文件夹、可执行文件、还有一个embedded.mobileprovision文件(从App Store下载的安装包是没有这个文件的,因为从App Store下载的安装包的签名机制不同)、还有一个_CodeSignature文件夹。
一、embedded.mobileprovision文件
在苹果后台的注册信息,就是我们从苹果开发者网站下载的描述文件。文件包含几个部分:
说明部分:包含APP ID
ENTITLEMENTS:权限信息,比如推送、健康
CERTIFICATES:证书信息,苹果私钥签名Mac公钥得到的证书。
PROVISIONED DEVICES:设备信息,苹果后台注册过的设备才可以安装。
当我们在设备上安装一个xxx.app时,如果安装失败,很大可能是因为验证阶段无法通过导致的。
举个例子:
当我们在一个非授权的设备上安装时,安装失败。因为embedded.mobileprovision文件验签成功后,要比对设备列表,当该设备不在列表内时,无法安装。
二、CodeResources文件
用文本编辑器打开该文件,发现其数据格式是xml格式,那么我们把文件加后缀.plist变为CodeResources.plist文件后用xcode打开。
在 CodeResources 文件中会有4个不同区域,其中的 rules 和 files 是为老版本准备的,而 files2 和 rules2是为新的第二版的代码签名准备的。最主要的区别是在新版本中你无法再将某些资源文件排除在代码签名之外,在过去你是可以的,只要在被设置签名的程序包中添加一个名为 ResourceRules.plist 的文件,这个文件会规定哪些资源文件在检查代码签名是否完好时应该被忽略。但是在新版本的代码签名中,这种做法不再有效。所有的代码文件和资源文件都必须设置签名,不再可以有例外。在新版本的代码签名规定中,一个程序包中的可执行程序包,例如扩展 (extension),是一个独立的需要设置签名的个体,在检查签名是否完整时应当被单独对待。
可以看到该文件内是整个xxx.app包内的文件的哈希值。
1、下面我们先来验证下截图中的hash
通过以下指令查看文件AppIcon20x20@2x.png的SHA1值:
$ openssl dgst -sha1 AppIcon20x20@2x.png
SHA1(AppIcon20x20@2x.png)= 6a86ffb8b561ef861b7f89630d476aa2d404db35
可以看到截图中的hash值与我们终端中的值是一致的。
2、下面我们先来验证下截图中的hash2
通过以下指令查看文件AppIcon20x20@2x.png的SHA256值:
$ openssl dgst -sha256 AppIcon20x20\@2x.png
SHA256(AppIcon20x20@2x.png)= 93bffc9b64344b715324fe393cbd56a90fa6be6c9ec2213c3e9fb13c62ecfb7d
可以看到截图中的hash2值与我们终端中的值是一致的。
3、当我们在设备上安装一个xxx.app时,如果安装失败,可能是因为破坏了文件的哈希值。
举个例子:
当我们改变了包内的某一个图片时,安装会失败。因为这个图片的hash值变了,验签时就会失败。
三、可执行文件
CodeResources里面的签名信息只是包含了资源文件(图片\nib\等等),而最终要的二进制文件不列在其中,这是咋回事?
因为可执行文件的签名是内嵌式的,其签名信息位于二进制中,详细还需了解关于Mach-O文件格式的介绍。
xcode签名配置
在开发中我们经常要配置证书、描述文件,我们看看究竟干了什么?
1、配置项看下图
Code Signing Entitlements:app的权限文件,验签时需要与Provision Profile中的权限比对是否一致。
Code Signing identity:可用于签名App的证书(带私钥)
Provisioning Profile:苹果私钥签名的描述文件,会被打包进xxx.app内就是embedded.mobileprovision
2、什么是带私钥的证书,看下图。
这就是我们从其它同事处获取的p12文件安装后在钥匙串内显示的证书,专用秘钥就是private key,说明所带的私钥是来自于王**的Mac生成的。
验签逻辑
当我们往一个设备安装时会经历以下几个阶段:
1、签名的xxx.app拷贝到设备,xxx.app内有embedded.mobileprovision文件、CodeResources文件
2、苹果公钥验签embedded.mobileprovision文件,验签成功说明描述文件合法,文件内的信息(APPID,设备、权限)都在苹果后台注册过(描述文件的合法性)。
3、比对设备IDs、APPID、Entitlements,比对成功才允许在该设备上安装。(滥装问题解决)。
4、苹果公钥验签embedded.mobileprovision包含的证书,验签成功说明是苹果签发的证书。(证书的合法性)
5、用证书验签App,验签成功才可以安装到该设备。该步的验签包括可执行文件的验签和资源文件的验签。可执行文件的验签在Mach-O文件内部。资源文件的验签会对比CodeResource文件的哈希值来确认文件是否被修改。(完整性问题解决)。
行者常至,为者常成!