iOS 代码签名

手机是如何确保从app store下载的app是没被恶意篡改,以及如何验证app开发者身份的呢?


一、数字签名(digit signruare)

数字签名基于公钥加密技术,能够验证数据的完整性和真实性。涉及公钥、私钥、数字证书,私钥用来签名,公钥用来验证,数字证书验证用户身份。

签名

签名过程使用哈希函数和私钥加密得到数字签名。

  • 经过哈希函数处理的数据得到一串固定长度且唯一的哈希值,即原始数据被更改后经过相同的哈希函数处理将得到不同的值。而且,该过程不可逆,即用处理结果推不出原始数据,这保证了数据的完整性。
  • 用私钥加密该哈希值,就得到数据的数字签名。私钥是用户自己保存,公钥是公开的,与私钥配对使用。只有用与私钥配对的公钥的才能对数字签名解密,这就保证了数据的真实性,即数据确实是某用户加密的。

签名过程:将原始数据经过哈希函数处理,得到哈希值;用私钥加密得到的哈希值,得到数字签名值s1。如图,


验证

将原始数据用签名过程相同的哈希函数处理,得到哈希值h1;接着使用公钥解密s1,得到h2。比较h1和h2值,如果两者相等,验证成功。不相等,验证失败。如图,


验证.png

数字证书

数字签名可以确保数据没有被篡改,但仍有一个问题。任何人都能申请一对公私钥,那如何知道解密的公钥就是某个用户的呢?这时就要用户向一个证书认证机构(Certification Authority,简称CA)申请一个数字证书,将用户的信息和用户的公钥,以及该CA的信息绑定在一起。将这些信息用CA的私钥进行数字签名,该数字签名和用户信息、用户公钥、CA信息组成了数字证书。


数字证书.png

数字证书验证:CA的公钥生产手机时就被导入系统的,是可信赖的。所以用该公钥可以验证数字证书的真实性。


数字证书申请

数字证书是数字签名的基础,是用来验证用户身份的证明。那如何向苹果公司申请数字证书(即开发者证书)呢?
在申请证书之前,应在本地电脑生成一个CSR文件(CertificateSigningRequest),CSR文件是证书请求文件,使用keychain生成,同时生成一对密钥:公钥和私钥。私钥保存在keychain中,CSR文件绑定该公钥和一些证书申请信息。
开发者用CSR文件向苹果开发者网站申请数字证书(开发者证书)。苹果将CSR内的公钥和开发者信息绑定在一起进行数字签名,生成开发者证书(以.cer为后缀)。详细申请信息可参考这里

注意

  • CSR文件没有私钥,申请到的开发者证书也没有私钥,私钥是保存到本地的。双击开发者证书安装到keychain,证书将自动绑定对应的私钥。
  • 如果将开发者证书安装到其他电脑(非生成CSR文件的电脑),该证书是没有私钥的。前面说过,私钥是用来签名的,所以该证书在其他电脑不能用来签名。
  • 如果想其他电脑也能签名,就需要在生成CSR文件的电脑上,将开发者证书导出为.p12证书文件。
  • .p12文件基于PKCS#12标准,包含私钥和证书在同一个文件,并用密码来保护。

有配对私钥的证书下面有个小钥匙。在Mac上通过keychain可以查证书内容。



iOS代码签名与验证

签名

xcode在为app签名时,并不是一次将整个安装包进行签名的。而是将每个文件独自签名,采用的规则如下:

  • Mach-O可执行文件:独自签名后,将签名数据写入到该可执行文件中。
  • 资源文件:将所有资源文件,比如图片,plist文件等独自签名,并且将签名信息记录在_CodeSignature/CodeResources文件中。

开发者只需要在xcode设置有效的开发者证书(包含私钥),在编译过程中,自动会将代码签名。我们也可以使用codesign命令签名,或者查看签名信息。

  • 查看系统中可以用来对代码进行签名的证书
$ security find-identity -v -p codesigning
  1) 6F58B7E08291BFFEB94746AE4416331679BB3ED3 "iPhone Developer: 1666522608@qq.com (DY6MN4A4Y8)"
  • 为app设置签名
$ codesign -s 'iPhone Developer: 1666522608@qq.com (DY6MN4A4Y8)' Example.app
  • 删除已存在的签名,重新为app设置签名,加上-f参数
$ codesign -f -s 'iPhone Developer: 1666522608@qq.com (DY6MN4A4Y8)' Example.app
  • 查看签名信息
$ codesign -vv -d Example.app
Executable=/Users/apple/Library/Developer/Xcode/DerivedData/Example-IOSegobnxqrpyiplcezotfhlhohfykp/Build/Products/Debug-iphoneos/Example.app/v2ex
Identifier=singro.v2ex.qh
Format=app bundle with Mach-O universal (armv7 arm64)
CodeDirectory v=20400 size=35314 flags=0x0(none) hashes=1095+5 location=embedded
Signature size=4800
Authority=iPhone Developer: 1666522608@qq.com (DY6MN4A4Y8)
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Signed Time=2018年10月30日 17:26:44
Info.plist entries=35
TeamIdentifier=J5FZC7U82Y
Sealed Resources version=2 rules=13 files=44
Internal requirements count=1 size=180

验证

app在安装前进行验证,分为两步:

  1. 用苹果私钥验证开发者证书;
  2. 用开发者的公钥验证安装包。

使用codesign命令验证:

$ codesign --verify Example.app

配置文件(provisioning profile)

有了开发者证书,才能验证开发者的身份,以及app安装包。那么系统是如何拿到开发者证书的呢?这就是配置文件要做的事情,它绑定了开发者的证书、app id、entitlements(授权)信息等。在xcode打包完成后,配置文件被放置在app安装包中。

配置文件是一个根据密码讯息语法 (Cryptographic Message Syntax) 加密的文件,采用 CMS 格式进行加密使得配置文件可以被设置签名,所以在苹果给你这个文件之后文件就不能被改变了。

使用security可以查看配置文件的信息。

$ security cms -D -i example.mobileprovision

开发者证书被包含在DeveloperCertificates选项里面,所有的证书都是基于 Base64 编码符合 PEM (Privacy Enhanced Mail, RFC 1848) 格式的。要查看一个证书的详细内容,将编码过的文件内容复制粘贴到一个文件中去,像下面这样:

-----BEGIN CERTIFICATE-----
MIIFnjCCBIagAwIBAgIIE/IgVItTuH4wDQYJKoZIhvcNAQEFBQAwgZYxCzA…
-----END CERTIFICATE-----`

然后使用 openssl x509 -text -in file.pem来显示证书详细内容。

小结

app代码签名基于数字签名,涉及了公钥、私钥、数字证书。私钥用于签名,公钥用于验证,数字证书用于证明开发者身份。iOS开发者先在本地生成CSR文件,然后用该CSR文件向苹果开发者中心申请开发者证书。在xcode设置有效的证书后,在构建过程中使用开发者的私钥进行签名。手机在安装app前先验证开发者证书,然后用开发者的公钥验证app安装包。开发者证书被绑定在配置文件(provisioning profile)内,并且配置文件在构建完成后被放置在app安装包内。

参考

Code Signing Guide
iOS代码签名(Code Signing)
代码签名探析
iOS Code Signing

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容