App的签名机制 【Xcode是如何将App安装到手机的】
-
iOS签名机制,保证安装到用户手机上的app都是经过apple官方允许的,现在xcode已经自动实现了下述操作
- 生成
certificateSigningRequest.cerSigningRequeset
文件,mac的公钥及其他信息打包后的csr
文件 - 获得ios_*.cer证书,CA用apple后台pri加密生成,一次签名
- 注册device,添加appid
- 获得
*.mobileprovision
文件,选证书+appid+device再用apple的pri加密后的文件 二次签名
- 生成
XCode签名需要用到的理论知识
- RSA加密算法,一种非对称的加密算法,用于通信。这种算法通常是客户端持有公钥,服务端持有私钥。客户端利用公钥加密。服务端可以用私钥解密。服务利用私钥加密数据发给客户端,客户端可以利用公钥解密出来。【简单来说就是:公钥加密的数据,利用私钥可以解密;私钥加密的数据,公钥同样能解密】
- 数字签名 客户端把【数据】,并利用公钥加密【数据的MD5】,然后把这【数据】与【机密后的MD5】发给服务器 服务器获取到数据包后,先求出【数据】的MD5,并解密【数据的MD5】,然后两者进行对比,如果不一样就代表数据被截获串改了
XCode如何将App安装到手机的【首先这个流程会涉及到2次数字签名】
- 从appstore下载安装的没有
*.mobileprovision
文件的
- Mac电脑本地生成公钥和私钥,通过CSR(cerfification signing request) 把自己的公钥打包成CSR文件发给服务器。
- 苹果服务器利用自己的私钥,对 Mac电脑的公钥进行数字签名,生成证书与描述文件,将证书与描述文件返回给Mac电脑。 一次签名
- Mac电脑利用私钥对App的可执行文件的Hash值进行加密,生成App的签名 二次签名
- Mac 将 App的可执行文件、App的签名、证书【关联Mac的私钥】、描述文件 打包成一个App传输给手机
- 手机将会使用苹果的公钥,对证书解析,获得Mac的公钥。利用Mac的公钥,解析App签名,获取Hash值进行认证,认证成功则App成功安装上,认证失败就无法安装。
# 查看csr文件信息
openssl req -noout -text -in CertificateSigningRequest.certSigningRequest
#授权机制(Entitlements)
- 简单说它就是一个沙盒的配置列表,上面列出了哪些行为被允许,哪些会被拒绝
- codesign -d -entitlements -xx.app 查看授权列表
- 常见的 get-task-allow true
- codesign -d -entitlements -xx.app 查看授权列表
#配置文件(Provisioning)
- appid
- 使用的证书
- 功能授权列表
- 可安装的设备列表
- 苹果签名
#重签名的四种方式
#####重签名APP
- 手动重签名【这种方法很复杂,容易出错,不过更接近原理】
- 使用Xcode进行重签名【在手动重签的基础上,利用XCode的功能执行部分操作,这种方法比较简单】
- 使用XCode脚本自动签名【首选的方法】
- 使用Monkey自动签名【Monkey的原理其实就是第三种方法】
#手动重签名APP
- 准备,【砸壳有两种方式(Clutch、dumpdecrypted)现在暂时从PP助手上面下载IPA包】
- 解压ipa,找到Payload文件夹下的 .app 文件
- 如何判断一个APP是否被砸过壳 砸过壳的App会有两个特点:没有签名信息和已经解过密了
- 查看.app文件的签名信息
$codesign -vv -d /Users/liangze/Desktop/砸壳的APPS/i11/i11/TargetApp/i9/Payload/kdweibo.app => Executable=/Users/liangze/Desktop/砸壳的APPS/i11/i11/TargetApp/i9/Payload/kdweibo.app/kdweibo Identifier=com.kdweibo.client Format=app bundle with Mach-O universal (armv7 arm64) CodeDirectory v=20500 size=825694 flags=0x0(none) hashes=12896+7 location=embedded Signature size=4390 Authority=(unavailable) //权限这个地方是unavailbale(不可用) Info.plist=not bound TeamIdentifier=8M8Y7973D3 Sealed Resources version=2 rules=45 files=1495 Internal requirements count=1 size=100
- 查看.app文件里面可执行文件的加密信息 获取给可执行文件的加密信息
.app/可执行文件
$otool -l kdweibo | grep crypt => cryptoff 16384 cryptsize 46481408 cryptid 0 cryptoff 16384 cryptsize 50298880 cryptid 0
因为cryptid的值为0,代表已经被解密了,砸壳是PP助手帮我们做的
- 开始手动去重签名
- 由于 Plugins/Wacth 里面是一些拓展插件 个人的证书没办法签extension,签名后无法正常安装到手机上,需要删掉
Monkey的签名脚本中是这样删的 - 签名extension 是一样的 codesign -fs "iPhone Developer: 泽 梁 (WVZ5JP3N7M)" ....
$rm -rf "$TARGET_APP_PATH/PlugIns" || true $rm -rf "$TARGET_APP_PATH/Watch" || true
- 需要对APP用到的每一个动态库【framework/dylib】进行签名
- 首先签名需要你有苹果开发者账号的开发证书
- 查看我们可以用来签名的证书信息
$security find-identity -v -p codesigning => 1) 84C7A63045A87D9A9A2EDDDA44B7BFB3EA16E268 "iPhone Distribution: Beijing Rongzhi Technology Co., Ltd. (58Y74FY8QK)" 2) D7708AE17558290755DC44A5B3460AA5A3FF2466 "iPhone Developer: 泽 梁 (WVZ5JP3N7M)"
-
签名动态库【这里需要把.app/Frameworks目录下的所有动态库进行签名】
$codesign -fs "iPhone Developer: 泽 梁 (WVZ5JP3N7M)" YZJEvent.framework
$codesign -fs "iPhone Developer: 泽 梁 (WVZ5JP3N7M)" Lottie.framework
$codesign -fs "iPhone Developer: 泽 梁 (WVZ5JP3N7M)" FLAnimatedImage.framework
$codesign -fs "iPhone Developer: 泽 梁 (WVZ5JP3N7M)" ExMasonry.framework
$codesign -fs "iPhone Developer: 泽 梁 (WVZ5JP3N7M)" ExCountly.framework
$codesign -fs "iPhone Developer: 泽 梁 (WVZ5JP3N7M)" Differentiator.framework
"" -
给.app下的可执行文件执行权限
$ls -l kdweibo 查看文件权限 => -rwxr-xr-x@ 1 liangze staff 115532224 11 8 2018 kdweibo $chmod +x kdweibo $ls -l kdweibo 查看文件权限 => -rwxr-xr-x@ 1 liangze staff 115532224 11 8 2018 kdweibo
- 添加描述文件(可以在编译器编译后,对Products->.app点show in finder拿 embedded.mobileprovision),
同时,修改Info.plist里面的BundleID ,这个要和mobileprovision里的是一样的 - 生成权限文件 通过我们刚才生成描述文件中,查询出权限信息
新建一个Entitlements.plist文件把权限信息拷贝进来,这样就得到我们自己的权限文件了,这个可以保存着一直用,只改bundlerID。
$security cms -D -i /Users/liangze/Documents/VSCode/ARM/embedded.mobileprovision => <key>Entitlements</key> <dict> <key>com.apple.security.application-groups</key> <array></array> <key>application-identifier</key> <string>58Y74FY8QK.com.fbbc.supi9</string> <key>keychain-access-groups</key> <array> <string>58Y74FY8QK.*</string> </array> <key>get-task-allow</key> <true/> <key>com.apple.developer.team-identifier</key> <string>58Y74FY8QK</string> </dict>
- 把新的权限文件放到.app文件的同级目录下,使用权限文件,签名整个APP
$codesign -fs "iPhone Developer: 泽 梁 (WVZ5JP3N7M)" --no-strict --entitlements=Entitlements.plist kdweibo.app
- 装到手机上 使用 Devices and Simulators 成功安装到手机上
- 检查iOS IPA文件的签名信息 用81行的 命令查看 .app里的 mobileprovision $security cms -D -i embedded.mobileprovision
- 由于 Plugins/Wacth 里面是一些拓展插件 个人的证书没办法签extension,签名后无法正常安装到手机上,需要删掉
#使用XCode脚本自动签名【仿照Monkey】 在项目下创建一个APP的文件夹,只要在哪个文件夹放置ipa包,就能制动重签名安装到自己的手机
- 先将需要重签名的ipa包放置到APP目录下
- 在项目运行前执行脚本 sh autoResigning.sh