一、ipa签名相关指令
1、快捷查看系统中能用来对代码进行签名的证书
//可以使用如下命令:
$security find-identity -v -p codesigning
) B3991DEFAEEC7CD640A4093FAD72FF642D6F4FCA "iPhone Distribution: Beijing Certificate Authority Co., Ltd." (CSSMERR_TP_CERT_REVOKED)
//这就说明当前有一个同时有公钥和私钥的可用证书。
2、对未签名app手动签名
$ codesign -s 'iPhone Distribution: Beijing Certificate Authority Co., Ltd.' Example.app
3、对已签名app重新签名
//为了重新设置签名,你必须带上 -f 参数,有了这个参数,codesign 会用你选择的签名替换掉已经存在的那一个:
$ codesign -f -s 'iPhone Distribution: Beijing Certificate Authority Co., Ltd.' Example.app
4、查看指定app的签名信息
//codesign 还可以为你提供有关一个可执行文件签名状态的信息,这些信息在出现不明错误时会提供巨大的帮助:
$ codesign -vv -d Example.app
5、验证签名文件的完整性
//检查已签名的文件是否完整可以使用如下命令:
$ codesign --verify Example.app
//就像大多数 UNIX 工具一样,没有任何输出代表签名是完好的。如果修改一下这个二进制文件:
$ echo 'lol' >> Example.app/Example
$ codesign --verify Example.app
Example.app: main executable failed strict validation
//和预料中的一样,修改已经签名的应用会导致数字签名验证不通过。
二、ipa签名相关文件
1、资源文件签名
* * * 签名值的村存放位置?* * *
经过观察CodeResources文件存放的貌似不是签名值,而是程序包内的各个文件的hash值的base64,具体签名值的存放位置还不是很清楚。
iOS 和 OS X 的应用和框架则是包含了它们所需要的资源在其中的。这些资源包括图片和不同的语言文件,资源中也包括很重要的应用组成部分例如 XIB/NIB 文件,存档文件(archives),甚至是证书文件。所以为一个程序包设置签名时,这个包中的所有资源文件也都会被设置签名。
为了达到为所有文件设置签名的目的,签名的过程中会在程序包(即Example.app)中新建一个叫做 _CodeSignatue/CodeResources 的文件,这个文件中存储了被签名的程序包中所有文件的签名。你可以自己去查看这个签名列表文件,它仅仅是一个 plist 格式文件。
这个列表文件中不光包含了文件和它们的签名的列表,还包含了一系列规则,这些规则决定了哪些资源文件应当被设置签名。伴随 OS X DP 和 版本的发布,苹果改变了代码签名的格式,也改变了有关资源的规则。如果你使用或者更高版本的 codesign 工具,在 CodeResources 文件中会有个不同区域,其中的 rules 和 files 是为老版本准备的,而 files2 和 rules2 是为新的第二版的代码签名准备的。最主要的区别是在新版本中你无法再将某些资源文件排除在代码签名之外,在过去你是可以的,只要在被设置签名的程序包中添加一个名为 ResourceRules.plist 的文件,这个文件会规定哪些资源文件在检查代码签名是否完好时应该被忽略。但是在新版本的代码签名中,这种做法不再有效。所有的代码文件和资源文件都必须 设置签名,不再可以有例外。在新版本的代码签名规定中,一个程序包中的可执行程序包,例如扩展 (extension),是一个独立的需要设置签名的个体,在检查签名是否完整时应当被单独对待。
2、授权文件(entitlements)
在 iOS 上你的应用能做什么依然是沙盒限制的,这些限制大多情况下都由授权文件(entitlements)来决定。授权机制决定了哪些系统资源在什么情况下允许被一个应用使用,简单的说它就是一个沙盒的配置列表。
运行如下命令:
$ codesign -d --entitlements - Example.app
会得到类似的结果:
<!--?xml version="1.0" encoding="UTF-8"?-->
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>7TPNXN7G6K.ch.kollba.example</string>
<key>aps-environment</key>
<string>development</string>
<key>com.apple.developer.team-identifier</key>
<string>7TPNXN7G6K</string>
<key>com.apple.developer.ubiquity-container-identifiers</key>
<array>
<string>7TPNXN7G6K.ch.kollba.example</string>
</array>
<key>com.apple.developer.ubiquity-kvstore-identifier</key>
<string>7TPNXN7G6K.ch.kollba.example</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.ch.kollba.example</string>
</array>
<key>get-task-allow</key>
<true>
</true></dict>
</plist version="1.0">
在 Xcode 的 Capabilities 选项卡下选择一些选项之后,Xcode 就会生成这样一段 XML。 Xcode 会自动生成一个 .entitlements 文件,然后在需要的时候往里面添加条目。当构建整个应用时,这个文件也会提交给 codesign 作为应用所需要拥有哪些授权的参考。这些授权信息必须都在开发者中心的 App ID 中启用,并且包含在后文介绍的描述文件中。在构建应用时需要使用的授权文件可以在 Xcode build setting 中的 code signing entitlements中设置。
在新版本的 Xcode 6 之后,授权信息列表会以 Example.app.xcent 这样的名字的文件形式包含在应用包中。这么做或许是为了在出现配置错误时提供更加有用的错误信息。
3、描述文件
在整个代码签名和沙盒机制中有一个组成部分将签名,授权和沙盒联系了起来,那就是描述文件 (provisioning profiles)。
OS X中保存目录
Xcode 将从开发者中心下载的全部配置文件都放在了这里:
~/Library/MobileDevice/Provisioning Profiles
文件格式
描述文件并不是一个普通的plist文件,它是一个根据密码讯息语法 (Cryptographic Message Syntax) 加密的文件。
以XML格式查看该文件的命令:
$ security cms -D -i example.mobileprovision
文件内容
描述文件主要包含以下内容:
· UUID
每一个配置文件都有它自己的 UUID 。Xcode 会用这个 UUID 来作为标识,记录你在 build settings 中选择了哪一个配置文件。
· ProvisionedDevices
记录所有可用于调试的设备ID。
· DeveloperCertificates
包含了可以为使用这个配置文件的应用签名的所有证书。所有的证书都是基于 Base64 编码符合 PEM (Privacy Enhanced Mail, RFC ) 格式的。
· Entitlements
有关前面讲到的配置文件的所有内容都会被保存在这里。
参考:
1、https://objccn.io/issue-17-2/ 《代码签名探析》
2、https://www.objc.io/issues/17-security/inside-code-signing/ 《Inside Code Signing》