(八)代码签名 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

(七)创建配置文件 Provisioning Profile

作者:kim

时间:Apr 27, 2015

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

 

 

1. Provisioning Profile 是苹果独有的,安装在设备上的配置文件,后缀名是 .mobileprovision ,通常简称 PP 文件。

 

简单地说,PP 文件就是把 Certificates 个人证书、App ID(或者其它各种服务种类的 ID)、Device ID,三者捆绑起来。
Provisioning Profile = Signing Certificate + App(Service) ID + Device ID

 

F8BFE2AC-DFBA-4EB0-8E5D-EF3A3127103B

 

 

2. 简单地说,Provisioning Profile 用来描述哪些人开发的哪些 App(或者服务)能够在哪些 Device 上面运行的文件。

1)Provisioning Profile 决定 Xcode 用哪个证书(包含用户的公钥)/私钥组合(Key Pair / Signing Identity)来签署应用程序(Signing Product)。
2)在应用程序打包时,Provisioning Profile 被嵌入到 .ipa 包里。
3)安装应用程序时,Provisioning Profile 文件被拷贝到 iOS 设备中,运行该 iOS App 的设备也通过它来认证安装的程序。

 

1570862B-C15D-4B1D-B989-75AA59FF24DB

 

 

3. 在网站上访问 “Certificates, Identifiers & Profiles” -> Provisioning Profiles ,进入 iOS Provisioning Profiles 配置文件创建界面。

 

4373FC58-0C89-4A87-88EC-2F4878B651B0

 

4. 点击 “manually generate profiles” 或者右上角的 “+” 号,挑选配置文件的类型。这里我们需要的是 Development 开发型配置文件。

 

9E696E05-D50F-4DE8-A72B-E5532C5BA0FC

 

5. 点击 Continue,选择要包含的 App ID 。

 

B5082CC2-40A9-415F-A64C-B7D00B315FF0

 

6. 点击 Continue,选择要包含的证书 Certificate(可多选)。注意,被签名加密的 App 的相应的那个证书必须被添加进去!

 

95913795-B1D2-4372-B128-80362D143BBF

 

7. 点击 Continue,选择设备 Devices(可多选)。

 

F5A95363-E0E3-4BD9-AE65-501FA5336B43

 

8. 继续点 Continue,给 Provisioning Profile 配置文件起名。

 

61370B88-A3F0-409E-AB69-C59ED14216E2

 

9. 点击 Generate,生成配置文件。

 

04A71695-8256-4C6D-A95E-B5223E15D0D5

 

10. 点击 Download 下载 .mobileprovision 文件,这就是生成好的配置文件。不下载其实也是可以的,因为 Xcode 会帮你管理它。

 

1B53AE2E-8267-4F0F-88E4-FCAA4F28D920

 

11. 在网站的配置文件列表能看到,新的配置文件已经处于 Active 激活状态。

 

7080697B-F882-418C-8B51-ABC98651055D

 

12. 另一方面,Xcode 将全部配置文件,包括用户手动下载安装的,和 Xcode 自动创建的 iOS Team Provisioning Profile,都放在目录 ~/Library/MobileDevice/“Provisioning Profiles”/ 下。

 

F29CC206-3BA9-4974-881F-D8FC3449ECFE

 

13. 可以用 security 命令查看一下配置文件的内容,我们可以看到 PP 文件实际上是一个 XML 格式的 plist 文件。
$ security cms -D -i nameofppfile.mobileprovision

 

6450E3A9-A639-40ED-A92A-02E661B6047F

 

14. 注意到其中的 UUID 信息,就是每个 PP 文件的唯一标识,通常作为文件名前缀。

 

8D7ED105-8696-46DA-BCDF-B978286A1B85

 

 

15. 注意到 DeveloperCertificates 信息,这是一个数组,包含了所有的证书信息,证书(即data)都是基于 Base64 编码的,符合 PEM(Privacy Enhanced Mail, RFC 1848) 格式。

 

 

16. 因为一个证书可以存在于多个不同的配置文件之中,所以在实际开发中,如果用 Xcode 自己选择配置文件的话,可能存在不确定性。幸好,Xcode6 开始提供了选择配置文件的功能,让用户自己为项目选择合适的 Provisioning Profile!

 

9F7DC716-B6BC-4A81-8666-70592BE473D7

 

17. iOS 设备和 Mac 系统都使用 Provisioning Profile 中的开发/发布证书来判断 App 的合法性与完整性!

 

1)可信性:使用苹果根证书 AppleWWDRCA.cer 能正确地从证书中解密出 App(Executable Code)的内容摘要(Signature),则证明此 App 确实是经过苹果签发的,即确实是认证开发者发布的!
2)完整性:对 App(Executable Code)本身使用 PP 文件记录的哈希算法,计算出内容摘要(Signature),若与第一步得到的一致,则证明此 App 确实未被篡改过!

 

 

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

(六)登记设备及其 Device ID

作者:kim

时间:Apr 26, 2015

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

 

 

1. Device ID 就是苹果设备的唯一标识 Unique Device ID(UDID),每个设备都有且只有一个。

 

2. 要找到 UDID,可以把设备连接到 Mac ,打开 Xcode 的 Window -> Devices ,或者快捷键 shift + command + 2
在设备信息下面就可以看到 Identifier ,即 UDID 了!

 

E1468AE4-2EC2-4899-927E-95D8D7A4DF0E

 

3. 假如设备无法连接到 Xcode ,或者 Xcode 无法识别该设备,那么也可以打开 iTunes,在设备信息界面,点几下 ECID 位置,就可以看到 UDID 了,拷贝下来。

 

94821803-0C33-4B0B-BB53-26E7F603A771

 

4. Xcode 也是可以注册设备的,这里我们使用手动在网站添加的方法。访问 “Certificates, Identifiers & Profiles” -> Devices -> All ,进入设备登记界面。

 

4FA58DC6-59CB-44A2-BC21-DA01B62AC855

 

5. 点击 “manually register devices” 或者右上角的 “+” 号,进入添加设备号界面。

 

13ED32F0-D82B-48A9-87A2-50AF6BB7500F

 

6. 点击 Continue,再点击 Register,进入完成界面,会提示该 Device ID 已经注册完毕,并且提示你可以把它添加到 Provisioning Profiles 里面了!

 

1523A921-D191-4625-BFDB-604AAA963DF0

7. 当然,我们还可以在 Devices 列表对设备进行管理,比如修改或者删除。

 

 

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

(五)App ID 基础概念与创建过程

作者:kim

时间:Apr 26, 2015

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

 

 

1. 苹果的 App ID 其实是广义的,与 App 的关系是一对多的,表示用户开发的一个或者多个 App 集合。
你的 App 因为有了 App ID,才能安装在 iOS 设备上,以及连接 Apple Purchase、Apple Push Notification Service (APNs) 及其它服务。

 

2. 访问 “Certificates, Identifiers & Profiles” -> Identifiers -> App IDs ,就能看到创建 App IDs 的引导页,下面还有创建 “Pass Type IDs”,”Merchant IDs” 等服务类 ID 的功能。

 

C5B21D99-5173-4A0B-B638-153D93880822

 

 

3. 点击 “Register your App ID” 或者右上角的 “+” 按钮,到达 App ID 注册页面。这里我们填上 App ID 的描述名,为了简单我们使用 App 的名字作为描述,当然也可以用其他任何描述名。

 

61B9CB77-30B5-4A85-A1A7-55092024D529

 

4. 每个 App ID 由 “App ID Prefix” 和 “App ID Suffix” 组成,就是我们即将在下面看到的!

 

5. “App ID Prefix” 又称为 “Bundle Seed ID” 或者 “Team ID”,即 App ID 前缀。
它是在你创建 App ID 的时候,由 Apple 自动生成的 10 位随机唯一的数字+字符串,比如 WK12LFS12P 。
注意,它不需要在 Xcode 里面设置!

 

6. “App ID Suffix” 又称为 “Bundle ID”,由 “Organization Identifier” 和 “Product Name” 两部分组成!
Apple 建议的规范是 “com.domainname.applicationname”,比如 com.company.MyGreatApp(事实上我们必须这么做!)

 

72E14421-CA36-42B6-9801-8B045F06433D

 

第一个选项是 “Explicit App ID”,唯一的 App ID,用于唯一标识一个应用程序。APNs 及其它苹果服务,要求 App ID 拥有明确的 Bundle ID 才能使用!

 

F219CD9E-51A6-4D6C-BF13-BCA3F96BEC17

 

第二个选项是 “Wildcard App ID”,含有通配符的 App ID,用于标识一组应用程序。例如 “*” 表示所有应用程序。假如你有多个同一类的 App,它们之间共享相同的访问权限,或者它们只是个 Demo,或者内部 App ,而且不需要 iOS 额外的技术服务(比如 Apple Purchase)的话,那么也可以直接用模糊匹配,比如 com.company.* 或者干脆只是用一个 * 号。

 

BF3D3AEB-00C8-4E29-9B9E-C4917F7333F1

 

注意!这种 app id 仅仅是为了给开发使用的。仅能生成开发的 provisioning profile。发布的 provisioning profile 必须指定完整的APP ID!

 

7. 简单地说:Bundle Seed ID + Company Identifier + Product Name = App ID
App ID 例子:
WK12LFS12P.*
WK12LFS12P.com.company.*
WK12LFS12P.com.company.MyGreatApp

 

8. 再下面就是挑选你需要开启的 App Services 服务选项了。注意,其中大部分服务,都要求是 “Explicit App ID” 才能选择的!

 

28B9464C-DF93-4CD4-95E5-97340178E2BA

 

9. 填好所需要的服务后,点击 continue ,并观察生成的 App ID,注意其中的 Identifier 就是你这个 App ID 的最终形态!

 

8955240D-38AB-419E-9E21-355C7DB1501E

 

10. 点击 Submit 和 Done 按钮,App ID 创建成功,并且可以开始使用!

 

B82FD331-A2C9-4EBF-BD7C-F4D60DA5A9BF

 

 

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

(四)创建开发者证书

作者:kim

时间:Apr 26, 2015

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

 

 

1. 访问 https://developer.apple.com/membercenter/ ,点击 “Certificates, Identifiers & Profiles” ,访问证书管理界面。

 

EA0CB25F-B614-424E-999D-7C98549DA26E

 

2. 首先选择 Certificates ,准备生成证书。

 

620D2086-144C-4EEA-A5D8-2411AC909CB5

 

3. 去到 Certificates -> All 页面,我们看到介绍了2种生成证书的方法,第一种是用 Xcode 自动为你创建证书,第二种是通过网站由用户手动生成。我们选择第二种方法,这样更有利于我们理解整个过程。

 

048F383E-D282-4BFD-8526-69FF7274299F

 

4. 我们点击 “Certificate Signing Request” ,开始选择证书的类型,我们选择第一个 “iOS App Development”,即 iOS 应用开发证书。其它还有 APNs 独立证书、AppStore 上线证书、Apple Pay 证书等等。

 

A0D52330-E4F1-44BA-B62A-AE5E97075C42

 

5. 在这个页面所有证书类型的下面,我们还会见到中间证书(Intermediate Certificates)的提示,提供用户下载 “AppleWWDRCA.cer” 的链接。
实际上这个文件就是 Apple 的全球开发者根证书(Apple Root Certificate)。
对,就是公钥,意义等同 CA 的根证书!通常是 Xcode 自己安装好的,当然也可以自己下载,并手动安装到 Mac 上面。

 

8AA35427-E169-4BD8-906D-E122D60BAE8E

 

6. 为了满足好奇心,我们手动安装下吧,点击 “Worldwide Developer Relations Certificate Authority” 就会下载到 “AppleWWDRCA.cer” 这个文件,双击就安装到了 Keychain 里面。

 

61F298CC-099C-4EC5-8AB0-71821BEF9BB1

 

7. 选择好证书类型后,点击 continue 进入请求证书页面,这里提示你如何在 Mac 上生成 Certificate Signing Request(CSR)文件。CSR文件简单地说就是你的公钥/私钥对!
注意,CSR 文件尽量每个证书都制作一次,并且用不同名称区分开,这样增加安全性!

 

823B8335-F6BE-4DD9-A7F9-8B0027D8E79C

 

8. 选择 钥匙串访问 -> 证书助理 -> 从证书颁发机构请求证书 ,“证书颁发机构” 指的就是 Apple ,简单地说就是,你要把你的 CSR 文件(公钥)上传到 Apple ,让它用私钥给你加密签发证书!

 

B31048CB-127B-4AFB-84FA-8A54DF2490C4

 

9. “用户电子邮件”那里必须填写你的用户账号邮箱地址,“常用名称”那里随便填个喜欢的。选择把证书保存到磁盘,点击继续。

 

EF7F6E83-DAFF-4A72-AA7C-F905B3E81D1C

 

10. 到达密钥生成界面,一般保持默认选项就行了,即2048位的 RSA 算法生成公钥/私钥对!

 

EC2783B3-4D4D-463D-ADBB-960394ADEB11

 

11. 点击继续,生成 “CertificateSigningRequest.certSigningRequest” 文件。简单地说,这个文件就是你的“数字签名+公钥”,用来上传给 Apple ,然后 Apple 用其私钥加密,这样就成功签发合格的证书了!

 

F52481AC-D30B-4207-B37D-FB6ABA1864E1

 

这个过程相当于使用以下 openssl 命令生成公钥/私钥对。
$ openssl genrsa -out private.key 2048
$ openssl req -new -sha256 -key private.key -out CertificateSigningRequest.certSigningRequest

 

12. 这时我们可以在 Keychain 看到公钥/私钥对。

 

4E915ACF-AE35-459C-82B9-2431D41FE8A3

 

13. 回到浏览器的 “Add iOS Certificate” 界面,点击 continue 来到生成证书界面,点击 “Choose File” 把刚才保存下来的 “CertificateSigningRequest.certSigningRequest” 上传到苹果。

 

AA503823-03B8-4647-8E5E-C51086905A1C

 

14. 点击 Generate ,证书就被 Apple 签发了。

 

25B59D70-D8B5-46B3-AF15-55D296329E9B

 

15. 点击 Download 保存好开发者证书,我们可以看到,证书是以标准的 X.509 格式来生成的!

 

8ED2F1A5-8B3D-4C1E-A93D-7DBDF7854214

 

16. 双击证书,安装到 Keychain 里面。

 

78D8FAEF-DAC8-4986-BB5C-97AC6E18BE89

 

17. 然后在 Keychain 里面查看下自己的证书吧。

 

E94B5D07-7BDF-4471-9CFE-E2622CE49B7E

 

18. 现在回到 “Certificates, Identifiers & Profiles” ,能看到你的证书记录显示在 Certificates 列表中!

 

38167318-2133-4E13-BE33-A67D58E5DE82

 

19. 在实际中,开发证书 ios_development.cer 被苹果根证书 AppleWWDRCA.cer 解密,得出真实的公钥 public key 出来!

 

20. iOS 设备以及 Mac 系统,都使用 CA 证书(AppleWWDRCA.cer)来判断 Provisioning Profile 中的开发证书的合法性。
1)若用 AppleWWDRCA.cer 公钥能成功解密出证书,并得到用户真实公钥(Public Key)和内容摘要(Signature),则证明此证书确实是 AppleWWDRCA 所签发,即证书的可信性!
2)对证书本身使用哈希算法计算摘要(Signature),若与上一步得到的摘要一致,则证明此证书确实未被篡改过,及证书的完整性!

 

 

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