Bootstrap

provisioning profile文件解密

每个配置文件实际上都是一个用PKCS#7签名后的plist文件。PKCS一组公钥密码学标准。PKCS#7是加密消息语法的标准。苹果使用这个标准对plist文件进行签名,通过签名,OS(操作系统)可以验证被安装的程序是来自合法的开发者(通过验证可以知道plist文件中的内容有没有被修改过)。plist文件中的最后一部分是非常重要的,稍后你将知道为什么。

在Terminal(终端程序)中使用vi打开一个配置文件,可以看到类似如下的内容:


0<82>^^è^F      *<86>H<86>÷^M^A^G^B <82>^^Ù0<82>^^Õ^B^A^A1^K0   ^F^E+^N^C^B^Z^E^@0<82>^N®^F     *<86>H<86>÷^M^A^G^A <82>^N<9f>^D<82>^N<9b><?xml version="1.0" encoding="UTF-8"?>  
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">    
<plist version="1.0">   
<dict>


上面这部分内容是PKCS#7签名的头部。往下看到的许多内容才是真正的签名:

</dict>    
   </plist>     
   <82>^M²0<82>^Cù0<82>^Bá ^C^B^A^B^B^A^_0^M^F    *<86>H<86>÷^M^A^A^E^E^@0y1^K0   ^F^CU^D^F^S^BUS1^S0^Q^F^CU^D    
    ^S    
    Apple Inc.1&0$^F^CU^D^K^S^]Apple Certification Authority1-0+^F^CU^D^C^S$Apple iPhone Certification Authority0^^^W^M080521020415Z^W^M200521020415Z0Y1^K0 ^F^CU^D^F^S^BUS1^S0^Q^F^CU^D   

    ^S   
    Apple Inc.1503^F^CU^D^C^S,Apple iPhone OS Provisioning Profile Signing0<82>^A"0^M^F     *<86>H<86>÷^M^A^A^A^E^@^C<82>^A^O^@0<82>^A

 

注意观察上面内容的底部,可以看到类似这样的字符串:Apple Inc., Apple Certification Authority 和 Apple iPhone OS Provisioning Profile Signing,通过这些内容可以知道这个文件进行了数字签名。配置文件是通过iOS Provisioning Portal创建的。当你选择了App ID,以及适当数量的设备UDIDs和Entitlement之后,苹果会将所有的这些信息数字签名到配置文件(Provisioning Profile)中,这样iOS就可以验证配置文件是否真的由苹果分发。

 

当这个配置文件被数字签名之后,你可能会问“我如何验证这个签名?”,在Terminal程序中,你可以使用openssl程序进行验证。Openssl不仅可以验证签名,还可以将签名信息打印出来,在Terminal程序中输入如下内容就可以进行验证:

openssl smime -in /path/to/your.mobileprovision -inform der -verify

 

现在,如果你希望手动编辑一下配置文件。比如你想把苹果新设备的UDID添加到配置文件中(不通过Provisioning Portal)。编辑之后,验证会失败,并得到如下类似的信息:

openssl smime -in Key_Grinder_Beta_Dev.mobileprovision -inform der -verify
Error reading S/MIME message
10163:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:/SourceCache/OpenSSL098/OpenSSL098-47/src/crypto/asn1/tasn_dec.c:1315:
10163:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/SourceCache/OpenSSL098/OpenSSL098-47/src/crypto/asn1/tasn_dec.c:657:Field=signer_info, Type=PKCS7_SIGNED
10163:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:/SourceCache/OpenSSL098/OpenSSL098-47/src/crypto/asn1/tasn_dec.c:747:
10163:error:0D08403A:asn1 encoding routines:ASN1_TEMPLATE_EX_D2I:nested asn1 error:/SourceCache/OpenSSL098/OpenSSL098-47/src/crypto/asn1/tasn_dec.c:577:Field=d.sign,Type=PKCS7

profile详细文件分析

1.在plist字典中的第一项是“AppIDName.” 这是你在 iOS Provisioning Portal中给App ID指定的名字。
 
2.下一项是“ApplicationIdentifierPrefix.”  这是在创建App ID时,由provisioning protal生成的10个字符。在 iOS Provisioning Portal中称为Bundle Seed ID(App ID前缀)。
 
3.下一项“CreationDate” 是一个日期时间戳,表示这个Provisioning Profile文件被创建的时间。
 
4.接下来的“DeveloperCertificates”之所以很有趣是有原因的。首先,它是一个数组(array),所以这里面可以包含多个证书。不过在这里我只看到一个证书。其次,它是base64编码的开发者证书。你可以将<data>标签中的文本拷贝并粘贴到另外一个文件中(粘贴在“—–BEGIN CERTIFICATE—–”和 “—–END CERTIFICATE—–”之间)。
 
看起来是这样的:
1.-----BEGIN CERTIFICATE-----
2.MIIFnTCCBIWgAwIBAgIIDlfxd9Mb0+gwDQYJKoZIhvcNAQEFBQAwgZYxCzAJ
3.BgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBs
4.ZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBw
5.bGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlv
6.biBBdXRob3JpdHkwHhcNMTIwODAzMjEzNDQxWhcNMTMwODAzMjEzNDQxWjCB
7.kDEaMBgGCgmSJomT8ixkAQEMClc1OFo3OVc4WDkxMjAwBgNVBAMMKWlQaG9u
8.ZSBEZXZlbG9wZXI6IEpheSBHcmF2ZXMgKEU2TDg3NlFGTTYpMRMwEQYDVQQL
9.DAo5SzlGOUxDVjc0MRwwGgYDVQQKDBNNYXNzaXZlbHkgT3ZlcnJhdGVkMQsw
10.CQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANdD
11.4hK9TjfXqoe1p0WpxvEULd575mhDpaKkvuUPG29bFEDIQrf2h0DTIGbvu6rR
12.z09+nxI0JkN56A0JO2OygfJGG5hcKm78CRtNFrDrOksOKD12PJkubnxhAi4y
13.sMI9M5+WCE+zV48VwMMI7dHLG7Pg5irMaqecnqNpRCoKxMeeziki+fD3H7jU
14.MiC6CA7iKCVHoDZKycF9Q3CeA5+sGWO28IqDYbOiCdeFhaiLYVVZJlmdKjqU
15.gHBsQWjj/vCeyikf+Ls52pPrD9+e0VgBnzrK2RcDPdNZON9gVAp1GeNNsmte
16.gmHGMlEzpLXF3/4RxOr2eLQ5iy5W/2SBUWpdSRUCAwEAAaOCAfEwggHtMB0G
17.A1UdDgQWBBSQHWHglRuqJq0gR4KzILT29p9ZIDAMBgNVHRMBAf8EAjAAMB8G
18.A1UdIwQYMBaAFIgnFwmpthhgi+zruvZHWcVSVKO3MIIBDwYDVR0gBIIBBjCC
19.AQIwgf8GCSqGSIb3Y2QFATCB8TCBwwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5j
20.ZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFj
21.Y2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJt
22.cyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBh
23.bmQgY2VydGlmaWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjApBggrBgEF
24.BQcCARYdaHR0cDovL3d3dy5hcHBsZS5jb20vYXBwbGVjYS8wTQYDVR0fBEYw
25.RDBCoECgPoY8aHR0cDovL2RldmVsb3Blci5hcHBsZS5jb20vY2VydGlmaWNh
26.dGlvbmF1dGhvcml0eS93d2RyY2EuY3JsMA4GA1UdDwEB/wQEAwIHgDAWBgNV
27.HSUBAf8EDDAKBggrBgEFBQcDAzATBgoqhkiG92NkBgECAQH/BAIFADANBgkq
28.hkiG9w0BAQUFAAOCAQEAApeWS6BrVv0jOFY7F0kCUR5h/RrXaMnUwjyFsF6r
29.HilDf70nvgIgIohtK2Uez5lkYavyDBzQGsN6gHbGLvg+4camDfT28quRPumk
30.qcIwZBCyB5A11HGlrer0Jz6iev6NAX5SSODWbAuzXJBs72EKuwF/+pGB5x1n
31.2YsKuQd8nQ+vD7kIHenP4n7goY8RSv8QQ8DhIkkgXqSbnZ6Xp4DKSTWgzb0T
32.a28g57YJlFjYioqkVFDi+5BANXxL0lHNeLAPXIY+TqQ/MWho/F6L2ONZyNT6
33.K6cadeQuTDgimoiTIjUGnAAR33SW7rIfHJNr2tNEtKu/aerKYCfWDLHf0QK9
34.1g==
35.-----END CERTIFICATE-----
 
 
然后在终端程序中使用命令 openssl x509 -text -in MassivelyOverrated.pem,就可以看到证书的所有信息,如下所示:
1.Certificate:
2.    Data:
3.        Version: 3 (0x2)
4.        Serial Number:
5.            0e:57:f1:77:d3:1b:d3:e8
6.        Signature Algorithm: sha1WithRSAEncryption
7.        Issuer: C=US, O=Apple Inc., OU=Apple Worldwide Developer Relations, CN=Apple Worldwide Developer Relations Certification Authority
8.        Validity
9.            Not Before: Aug  3 21:34:41 2012 GMT
10.            Not After : Aug  3 21:34:41 2013 GMT
11.        Subject: UID=W58Z79W8X9, CN=iPhone Developer: Jay Graves (E6L876QFM6), OU=9K9F9LCV74, O=Massively Overrated, C=US
12.        Subject Public Key Info:
13.            Public Key Algorithm: rsaEncryption
14.            RSA Public Key: (2048 bit)
15.                Modulus (2048 bit):
16.                    00:d7:43:e2:12:bd:4e:37:d7:aa:87:b5:a7:45:a9:
17.                    c6:f1:14:2d:de:7b:e6:68:43:a5:a2:a4:be:e5:0f:
18.                    1b:6f:5b:14:40:c8:42:b7:f6:87:40:d3:20:66:ef:
19.                    bb:aa:d1:cf:4f:7e:9f:12:34:26:43:79:e8:0d:09:
20.                    3b:63:b2:81:f2:46:1b:98:5c:2a:6e:fc:09:1b:4d:
21.                    16:b0:eb:3a:4b:0e:28:3d:76:3c:99:2e:6e:7c:61:
22.                    02:2e:32:b0:c2:3d:33:9f:96:08:4f:b3:57:8f:15:
23.                    c0:c3:08:ed:d1:cb:1b:b3:e0:e6:2a:cc:6a:a7:9c:
24.                    9e:a3:69:44:2a:0a:c4:c7:9e:ce:29:22:f9:f0:f7:
25.                    1f:b8:d4:32:20:ba:08:0e:e2:28:25:47:a0:36:4a:
26.                    c9:c1:7d:43:70:9e:03:9f:ac:19:63:b6:f0:8a:83:
27.                    61:b3:a2:09:d7:85:85:a8:8b:61:55:59:26:59:9d:
28.                    2a:3a:94:80:70:6c:41:68:e3:fe:f0:9e:ca:29:1f:
29.                    f8:bb:39:da:93:eb:0f:df:9e:d1:58:01:9f:3a:ca:
30.                    d9:17:03:3d:d3:59:38:df:60:54:0a:75:19:e3:4d:
31.                    b2:6b:5e:82:61:c6:32:51:33:a4:b5:c5:df:fe:11:
32.                    c4:ea:f6:78:b4:39:8b:2e:56:ff:64:81:51:6a:5d:
33.                    49:15
34.                Exponent: 65537 (0x10001)
35.        X509v3 extensions:
36.            X509v3 Subject Key Identifier:
37.                90:1D:61:E0:95:1B:AA:26:AD:20:47:82:B3:20:B4:F6:F6:9F:59:20
38.            X509v3 Basic Constraints: critical
39.                CA:FALSE
40.            X509v3 Authority Key Identifier:
41.                keyid:88:27:17:09:A9:B6:18:60:8B:EC:EB:BA:F6:47:59:C5:52:54:A3:B7
42. 
43.            X509v3 Certificate Policies:
44.                Policy: 1.2.840.113635.100.5.1
45.                  User Notice:
46.                    Explicit Text: Reliance on this certificate by any party assumes acceptance of the then applicable standard terms and conditions of use, certificate policy and certification practice statements.
47.                  CPS: http://www.apple.com/appleca/
48. 
49.            X509v3 CRL Distribution Points:
50.                URI:http://developer.apple.com/certificationauthority/wwdrca.crl
51. 
52.            X509v3 Key Usage: critical
53.                Digital Signature
54.            X509v3 Extended Key Usage: critical
55.                Code Signing
56.            1.2.840.113635.100.6.1.2: critical
57.                ..
58.    Signature Algorithm: sha1WithRSAEncryption
59.        02:97:96:4b:a0:6b:56:fd:23:38:56:3b:17:49:02:51:1e:61:
60.        fd:1a:d7:68:c9:d4:c2:3c:85:b0:5e:ab:1e:29:43:7f:bd:27:
61.        be:02:20:22:88:6d:2b:65:1e:cf:99:64:61:ab:f2:0c:1c:d0:
62.        1a:c3:7a:80:76:c6:2e:f8:3e:e1:c6:a6:0d:f4:f6:f2:ab:91:
63.        3e:e9:a4:a9:c2:30:64:10:b2:07:90:35:d4:71:a5:ad:ea:f4:
64.        27:3e:a2:7a:fe:8d:01:7e:52:48:e0:d6:6c:0b:b3:5c:90:6c:
65.        ef:61:0a:bb:01:7f:fa:91:81:e7:1d:67:d9:8b:0a:b9:07:7c:
66.        9d:0f:af:0f:b9:08:1d:e9:cf:e2:7e:e0:a1:8f:11:4a:ff:10:
67.        43:c0:e1:22:49:20:5e:a4:9b:9d:9e:97:a7:80:ca:49:35:a0:
68.        cd:bd:13:6b:6f:20:e7:b6:09:94:58:d8:8a:8a:a4:54:50:e2:
69.        fb:90:40:35:7c:4b:d2:51:cd:78:b0:0f:5c:86:3e:4e:a4:3f:
70.        31:68:68:fc:5e:8b:d8:e3:59:c8:d4:fa:2b:a7:1a:75:e4:2e:
71.        4c:38:22:9a:88:93:22:35:06:9c:00:11:df:74:96:ee:b2:1f:
72.        1c:93:6b:da:d3:44:b4:ab:bf:69:ea:ca:60:27:d6:0c:b1:df:
73.        d1:02:bd:d6
74.-----BEGIN CERTIFICATE-----
75.MIIFnTCCBIWgAwIBAgIIDlfxd9Mb0+gwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNV
76.BAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3Js
77.ZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3
78.aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
79.HhcNMTIwODAzMjEzNDQxWhcNMTMwODAzMjEzNDQxWjCBkDEaMBgGCgmSJomT8ixk
80.AQEMClc1OFo3OVc4WDkxMjAwBgNVBAMMKWlQaG9uZSBEZXZlbG9wZXI6IEpheSBH
81.cmF2ZXMgKEU2TDg3NlFGTTYpMRMwEQYDVQQLDAo5SzlGOUxDVjc0MRwwGgYDVQQK
82.DBNNYXNzaXZlbHkgT3ZlcnJhdGVkMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcN
83.AQEBBQADggEPADCCAQoCggEBANdD4hK9TjfXqoe1p0WpxvEULd575mhDpaKkvuUP
84.G29bFEDIQrf2h0DTIGbvu6rRz09+nxI0JkN56A0JO2OygfJGG5hcKm78CRtNFrDr
85.OksOKD12PJkubnxhAi4ysMI9M5+WCE+zV48VwMMI7dHLG7Pg5irMaqecnqNpRCoK
86.xMeeziki+fD3H7jUMiC6CA7iKCVHoDZKycF9Q3CeA5+sGWO28IqDYbOiCdeFhaiL
87.YVVZJlmdKjqUgHBsQWjj/vCeyikf+Ls52pPrD9+e0VgBnzrK2RcDPdNZON9gVAp1
88.GeNNsmtegmHGMlEzpLXF3/4RxOr2eLQ5iy5W/2SBUWpdSRUCAwEAAaOCAfEwggHt
89.MB0GA1UdDgQWBBSQHWHglRuqJq0gR4KzILT29p9ZIDAMBgNVHRMBAf8EAjAAMB8G
90.A1UdIwQYMBaAFIgnFwmpthhgi+zruvZHWcVSVKO3MIIBDwYDVR0gBIIBBjCCAQIw
91.gf8GCSqGSIb3Y2QFATCB8TCBwwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5jZSBvbiB0
92.aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ug
93.b2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29uZGl0
94.aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlmaWNhdGlv
95.biBwcmFjdGljZSBzdGF0ZW1lbnRzLjApBggrBgEFBQcCARYdaHR0cDovL3d3dy5h
96.cHBsZS5jb20vYXBwbGVjYS8wTQYDVR0fBEYwRDBCoECgPoY8aHR0cDovL2RldmVs
97.b3Blci5hcHBsZS5jb20vY2VydGlmaWNhdGlvbmF1dGhvcml0eS93d2RyY2EuY3Js
98.MA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDAzATBgoqhkiG
99.92NkBgECAQH/BAIFADANBgkqhkiG9w0BAQUFAAOCAQEAApeWS6BrVv0jOFY7F0kC
100.UR5h/RrXaMnUwjyFsF6rHilDf70nvgIgIohtK2Uez5lkYavyDBzQGsN6gHbGLvg+
101.4camDfT28quRPumkqcIwZBCyB5A11HGlrer0Jz6iev6NAX5SSODWbAuzXJBs72EK
102.uwF/+pGB5x1n2YsKuQd8nQ+vD7kIHenP4n7goY8RSv8QQ8DhIkkgXqSbnZ6Xp4DK
103.STWgzb0Ta28g57YJlFjYioqkVFDi+5BANXxL0lHNeLAPXIY+TqQ/MWho/F6L2ONZ
104.yNT6K6cadeQuTDgimoiTIjUGnAAR33SW7rIfHJNr2tNEtKu/aerKYCfWDLHf0QK9
105.1g==
106.-----END CERTIFICATE-----
 
 
苹果和iOS使用这个证书来验证有开发者签过名的代码。
 
5.下一个是“Entitlements”这里面有一个字典,字典中有许多键值对,都是与iCloud、Game Center、推送通知和调试程序相关的一些内容。这里并不打算介绍这些相关的键值内容。如果你以前遇到这样的错误“The executable was signed with invalid entitlements”,可以将这个Entitlements字典拷贝并粘贴到程序的Entitlements.plist文件中,确保程序和Provisioning的entitlements都是精确匹配的。
 
6.“ExpirationDate”是这个Provisioning Profile文件的过期日期。
 
7.“Name”是在iOS Developer Portal给这个Provisioning Profile指定的名字。
 
8.“ProvisionedDevices”是一个数组,里面是一个设备UDID列表,这表示了利用这个Provisioning Profile签名的程序只能安装在这里列出来的UDID设备中(我是这样认为的)。一般我打开一个Provisioning Profile文件,都是看看某个设备的UDID是否已经包含在这个数组中了。
 
9.“TeamIdentifier”也包含一个数组,不过我只在这个数组中看到过一个值。这个值相当于一个标示符,用来唯一标识这个Provisioning Profile文件属于哪个团队。
 
10. “TeamName”表示这个Provisioning Profile文件属于团队的名称。有趣的是“TeamIdentifier”是数组,但是这里的 “TeamName”不是。
 
11. “TimeToLive”是这个Provisioning Profile文件的有效天数。苹果将这个值设置为365天。
 
12.  “UUID”这个值可以在Xcode工程文件中找到。每更新一次Provisioning Profile文件,这个UUID都会改变。如果你曾在Xcode中选择了某个特定的 Code Signing Identity,而不是 “iPhone Developer” 或“iPhone Distribution”,这个UUID可以在Xcode project.pbxproj文件中的“PROVISIONING_PROFILE”字段进行设置。在你将Xcode中的Provison Profile文件修改为另外一个,SCM会差分出如下结果:
1.- PROVISIONING_PROFILE = "D8F8CD60-CD85-4FEA-BF87-CD5D67FDC3EA";
2.+ PROVISIONING_PROFILE = "9B44F36C-328F-45C0-BC62-4A272CB9DAD7";
 
 
13.“Version”是这个文件数据格式的版本。苹果将其设置为1。
 
上面提到过,当我检查这个Provision Profile文件时,90%次都是检查 “ProvisionedDevices”数组。另外10%次是检查 “Entitlements” 和“UUID”。如果程序中使用了APNS(Apple’s Push Notification service),那么“Entitlements”这个字段将保存着apns的相关信息。这个值可以包含 “production” 或“development”的信息,也可以没有设置相关信息,不过这样的话在程序中就不能正常使用推送通知。一般在将程序提交到iTunes Connect时,我都会检查一下这个字段。
一般在Xcode中,我都是使用“UUID”来指定一个特定的Provisioning Profile文件,这样可以不依赖于Xcode的自动选择(经常会出问题)。Jenkins利用.xcconfig文件来覆盖“UUID”,可以让自动build更加容易。
(转自:http://www.cocoachina.com/applenews/devnews/2013/0501/6113.html


;