Because you have never seen the miracle. - 《银翼杀手2049》
超级签名是什么?
所谓的超级签名,其实一句话就能说清楚:使用了苹果提供给开发者的Ad-Hoc分发通道,把安装设备当做开发设备进行分发。
优势:直接分发,安装即可运行,不需要用户做企业证书的信任操作,不会有证书吊销导致的风险
劣势:成本昂贵,单开发者账号的iPhone设备数量只有100个,
实现流程
- 手机安装
.mobileconf
文件,将UDID发给服务器 - 服务器将收到的UDID注册到苹果开发者账号中,并更新描述文件
- 将更新后的描述文件来重签App
- 最后将重签的App上传至cdn,利用
itms-services
方式做分发下载
详细实现细节
准备好获取UDID的配置文件,也就是
.mobileconf
文件,文件内容大致如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<dict>
<key>URL</key>
<!– 接收数据的接口地址 –>
<string>http://106.54.214.191:443/udid/receive</string>
<key>DeviceAttributes</key>
<array>
<string>UDID</string>
<string>IMEI</string>
<string>ICCID</string>
<string>VERSION</string>
<string>PRODUCT</string>
</array>
</dict>
<key>PayloadOrganization</key>
<string>www.qianniuniu.com</string>
<key>PayloadDisplayName</key>
<string>Test</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadUUID</key>
<string>8C7AD0B8-3900-44DF-A52F-3C4F92921807</string>
<key>PayloadIdentifier</key>
<string>com.super.signature</string>
<key>PayloadDescription</key>
<string>该配置文件将帮助用户获取当前iOS设备的UDID号码。This temporary profile will be used to find and display your current device's UDID.</string>
<key>PayloadType</key>
<string>Profile Service</string>
</dict>
</plist>使用服务器https证书对配置文件签名
上图是服务器端生成的证书文件,这里使用的是Apache文件夹下面的
mbaike.crt
:https服务器端使用证书文件。
mbaike.key
:https服务器端使用证书对应的密钥。
root_bundle.pem
:与SSL证书对应的证书链(中级证书)。
unsigned.mobilecofig
文件:IOS端生成的未签名的配置描述文件。1
2
3
4
5
6
7
8
9# 再使用通过openssl命令生成签名后的signed.mobileconfig文件
openssl smime -sign -in unsigned.mobileconfig -out signed.mobileconfig -signer mbaike.crt -inkey mbaike.key -certfile root_bundle.pem -outform der -nodetach
# 也可以把key文件的密码写入到key文件中
openssl rsa -in mbaike.key -out mbaikenopass.key
# 第二步的命令就应该是
openssl smime -sign -in unsigned.mobileconfig -out signed.mobileconfig -signer mbaike.crt -inkey mbaikenopass.key -certfile root_bundle.pem -outform der -nodetach这样就完成了对
mobileconfig
的签名工作了上图是中点击 “获取UDID” ,就会跳到设置 -> 通用 -> 描述文件 去安装已经签名的描述文件
如图显示已签名,说明第二步对
.mobilecofig
的签名是OK的,安装成功后,返回下载页面并调用http://106.54.214.191:443/udid/receive
这个地址,服务器端就会收到UDID等信息利用开源工具Spaceship,注册新的开发者设备到苹果开发者中心,并更新 Provisioning Profile,服务器端使用的是 ruby 脚本来完成这个功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49#!/usr/bin/ruby -w
require "spaceship"
puts "======Hello, Write Start======"
# 先登录
Spaceship::Portal.login("1711218908@qq.com", "密码")
is_bundle = Spaceship.app.find("com.super01.signature")
if !is_bundle
Spaceship.app.create!(bundle_id: "com.super01.signature", name: 'iosudid')
end
#group权限
app = Spaceship::Portal.app.find("com.super01.signature")
group = Spaceship::Portal.app_group.find("group.com.super01.signature")
if !group
group = Spaceship::Portal.app_group.create!(group_id: "group.com.super01.signature",name: "Another group")
end
app = app.associate_groups([group])
app.update_service(Spaceship::Portal.app_service.network_extension.on)
app.update_service(Spaceship::Portal.app_service.access_wifi.on)
app.update_service(Spaceship::Portal.app_service.push_notification.on)
app.update_service(Spaceship::Portal.app_service.game_center.on)
# 新增设备的UDID
Spaceship::Portal.device.create!(name: "那年星空", udid: "***")
#更新设备
allDevices = Spaceship.device.all
device_profiles = Spaceship::Portal.provisioning_profile.ad_hoc.find_by_bundle_id(bundle_id: "com.super01.signature")
device_profiles.each do |profile|
profile.devices = allDevices
profile.update!
end
#下载描述文件
matching_profiles = Spaceship::Portal.provisioning_profile.ad_hoc.find_by_bundle_id(bundle_id: "com.super01.signature")
if matching_profiles.first
File.write("SuperSignatureAdHocProfile.mobileprovision", matching_profiles.first.download)
else
cert = Spaceship::Portal.certificate.production.all.first
profile=Spaceship.provisioning_profile.ad_hoc.create!(bundle_id: "com.super01.signature", certificate: cert, name: "com.super01.signature adhoc")
File.write("SuperSignatureAdHocProfile.mobileprovision", profile.download)
end
puts "====== Hello, Write End! ======"
制作.cer证书,这一步和我们平时做iOS开发一样,我就不多说了
重点来了,ipa包的重签,这里使用的是 zsign,将步骤3中更新后的描述文件和步骤4中的证书放在zsign项目的同一级目录下,如下图:
使用命令如下:
1
./zsign -k key.p12 -p 123 -m SuperSignatureAdHocProfile.prov -o output.ipa SASpecs.app
将重签好的ipa包上传至cdn服务器拿到下载链接,下一步开始制作分发文件。
分发文件(
manifest.plist
)需要准备两张图片的下载地址,文件内容如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<plist version="1.0">
<dict>
<key>items</key>
<array>
<dict>
<key>assets</key>
<array>
<dict>
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>https://qnnapk-1251122539.cos.ap-shanghai.myqcloud.com/SASpecs.ipa</string>
</dict>
<dict>
<key>kind</key>
<string>display-image</string>
<key>url</key>
<string>https://qnnapk-1251122539.cos.ap-shanghai.myqcloud.com/57.png</string>
</dict>
<dict>
<key>kind</key>
<string>full-size-image</string>
<key>url</key>
<string>https://qnnapk-1251122539.cos.ap-shanghai.myqcloud.com/512.png</string>
</dict>
</array>
<key>metadata</key>
<dict>
<key>bundle-identifier</key>
<string>com.super.signature</string>
<key>bundle-version</key>
<string>1.0</string>
<key>kind</key>
<string>software</string>
<key>platform-identifier</key>
<string>com.apple.platform.iphoneos</string>
<key>title</key>
<string>SASpecs</string>
</dict>
</dict>
</array>
</dict>
</plist>当用户下载这个分发文件后就会安装对应的ipa包,