签名原理:

解析:xcode怎么运行到手机上的?(苹果主要保证app安装时它认证的,并且是他有安装到指定的设备上,在app线上是没有这些描述文件)
第一步: mac电脑上要生成一对公钥M和私钥M (公钥是从私钥生成),CSR文件(包含公钥M,可以直接cat CSR文件看下面)(CSR文件包含信息看下面)中(也就是 钥匙串访问/证书助理/从证书颁发机构请求证书.. (CertificateSigningRequest.certSigningRequest))发给苹果服务器申请证书
|
-----BEGIN CERTIFICATE REQUEST----- MIICfTCCAWUCAQAwODEbMBkGCSqGSIb3DQEJARYMZDh0dkAxNjMuY29tMQwwCgYD VQQDDANtYWMxCzAJBgNVBAYTAkNOMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvx0xqkl0D7zdfFqViDKEpxgftqq0yN/HTmG8Go5w/qgNDOBOoZrCpFAI KwKzhaKt04JO3z/4B6F3CKcSCJ0OPCef3iBYQrfc+I5ONwTrg00X/knExThtbNvV 21iN1rAEoES3r7WEb+x+vbH+IBJVJtpBUraSlOlBhmKVmORNZq/7KA4X4gOC4cno hauCwEneWl7B+vN//VuAno9Yt8xvusumOL8Gwtyzi77fGiYVj+C9e8aSRGyZBSoO DfoM/XErcWYYsIPCVW0mrYSSxiyuk+qvA7HAQfIW4H57GUc9gd2bIjR3L8GZxjhN 6+TrFKH5aVJWDfDbfKG2cQHFSKy8dwIDAQABoAAwDQYJKoZIhvcNAQELBQADggEB AKefLgEFYZALY8qjwAqwnN7hrLAKMYiVSwyWe9pp77EiB2UUV4Vb3PZ6GE+4 cjvCr6nus7gztjYYtSjn7wXK1AaE6+q1oxsP9EElz9k6RtqgTMmwFs7AUkGmsDuD HcwXtxGC8a0MWgAGmuQ12NvQvZCjKf62LJxCXI1GAaLprpuabHyCyNCjXfXdm0+e eNy9gAMSa2EmmBGKy8U1dncOW/nynPL4LxNu+Hk8X0MXSUSaNzOusIkzsIHsPEF/ EWmpmWTcuD30nbL7m0H62J4= -----END CERTIFICATE REQUEST----- |
通过 命令获得
|
openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest |
CSR信息如下
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
|
0:d=0 hl=4 l= 637 cons: SEQUENCE 4:d=1 hl=4 l= 357 cons: SEQUENCE 8:d=2 hl=2 l= 1 prim: INTEGER :00 11:d=2 hl=2 l= 56 cons: SEQUENCE 13:d=3 hl=2 l= 27 cons: SET 15:d=4 hl=2 l= 25 cons: SEQUENCE 17:d=5 hl=2 l= 9 prim: OBJECT :emailAddress 28:d=5 hl=2 l= 12 prim: IA5STRING :d8tv@163.com 42:d=3 hl=2 l= 12 cons: SET 44:d=4 hl=2 l= 10 cons: SEQUENCE 46:d=5 hl=2 l= 3 prim: OBJECT :commonName 51:d=5 hl=2 l= 3 prim: UTF8STRING :mac 56:d=3 hl=2 l= 11 cons: SET 58:d=4 hl=2 l= 9 cons: SEQUENCE 60:d=5 hl=2 l= 3 prim: OBJECT :countryName 65:d=5 hl=2 l= 2 prim: PRINTABLESTRING :CN 69:d=2 hl=4 l= 290 cons: SEQUENCE 73:d=3 hl=2 l= 13 cons: SEQUENCE 75:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption 86:d=4 hl=2 l= 0 prim: NULL 88:d=3 hl=4 l= 271 prim: BIT STRING 363:d=2 hl=2 l= 0 cons: cont [ 0 ] 365:d=1 hl=2 l= 13 cons: SEQUENCE 367:d=2 hl=2 l= 9 prim: OBJECT :sha256WithRSAEncryption 378:d=2 hl=2 l= 0 prim: NULL 380:d=1 hl=4 l= 257 prim: BIT STRING |
第二步: 苹果用私钥S加密公钥M去生成证书一个证书和一个Provision profile文件,下载到本地,然后mac上会把私钥M和证书关联到一起(验证是否公私钥对应)也就是钥匙串中情况看图
比如如果别的mac也要编译app安装,要把私钥打成p12给他。其中证书包含mac上的公钥M和公钥M的hash值(防止篡改)
另外还有个Provision profile文件是注册的devices和cers等看图 ,可以通过这个路径找到(包含多个系统会进行匹配获取)
|
~/Library/MobileDevice/Provisioning Profiles |
可以通过命令得到描述文件的信息(是xml文件可以在xcode的plist查看,也就是下面图的内容):
|
security cms -D -i embe.mobileprovision |


第三步: 通过私钥M进行app加密签名和第2步的证书和Provision profile文件打包到app中
问题:怎么验证Provision profile文件加入到app中?
解压app后得到
其中有个embedded.mobileprovision就是第2步下载的描述文件,可以对比看下
第四步: 取出第3步的证书通过公钥A(苹果内置)进行解密得到公钥M(验证Hash值是否合法),然后通过公钥M解密app签名判断app是否被修改过,在手机上2次签名认证
问题:怎么签名证书在app中?
看上面解压app后的图 其中有个_CodeSignature/CodeResources这个就是,不止是app包中有,在macho可执行文件中也包含看图(通过machoView查看)

手动重签名 (重签app安装到手机上)
查看本电脑所以证书 (也就是~/Library/MobileDevice/Provisioning Profiles 路径下的证书)
|
security find-identity -v -p codesigning |
查看app是否签名?
|
Executable=/Users/frong/Downloads/app/微信-6.6.6(越狱应用)/Payload/WeChat.app/WeChat Identifier=com.tencent.xin Format=app bundle with Mach-O universal (armv7 arm64) CodeDirectory v=20200 size=503759 flags=0x0(none) hashes=15735+5 location=embedded Signature size=4297 Authority=(unavailable) Info.plist=not bound TeamIdentifier=88L2Q448 Sealed Resources version=2 rules=19 files=822 Internal requirements count=1 size=96 |
Authority=(unavailable) 没有签名信息 越狱应用,被砸过壳。如果有签名信息:
- Authority=Apple iPhone OS Application Signing
- Authority=Apple iPhone Certification Authority
查看app是否加密?
|
otool -l WeChat | grep crypt |
|
cryptoff 16384 cryptsize 55164928 cryptid 0 cryptoff 16384 cryptsize 59457536 cryptid 0 |
cryptid 0 没有加密的(这个是越狱应用),非越狱cryptid 1
- 解压app后其中这些Plugins插件个人账户没办法重签名,可以直接删除这个Plugins文件夹
- 其中有Watch也没办法重签名 直接删除
- 对Framework/所以framework要重签名
|
#codesign -fs 证书 framework codesign -fs "iPhone Developer: Rong (EGTRWsdMDR)" ma.framework |
4. 给可执行文件执行权限 (chmod +x WeChat)
5.把xcode中的Demo编译的app包的embedded.mobileprovision描述文件到Wechat的app包中
6.把xcode中Demo的BundleID赋值到Wechat的info.plist文件的名字中(可以使用通配符com.shengshui.* (后面名字随便起))
7.查看下WeChat中的描述文件(刚才copy的那个)
|
security cms -D -i embedded.mobileprovision |
找到权限文件Entitlements把<dict> </dict>copy生成entitlements.plist(可以用xcode生成)
8.把7步生成的entitlements.plist放在WeChat.app同级目录下
9.签名整个app
|
codesign -fs "iPhone Developer: Rong (EGTRWsdMDR)" --no-strict --entitlements=entitlements.plist WeChat.app |
10.把app搞到一个单独文件夹中打包成ipa
|
zip -ry WeChat.ipa Payload |
11.在Xcode中Widow/Devicesa and Simulators/Installed apps 点击+ 把ipa安装上就ok了


Xcode重签名
- 进入Xcode编译的Demo.app,找到越狱wechat.app 替换Demo.app (名字要一样 用Demo.app)
- Demo.app(上面被wechat替换的)显示包内容 找到info.plist文件把bundleID改为Demo的bundleID
- 对Framework/所以framework要重签名
-
|
#codesign -fs 证书 framework codesign -fs "iPhone Developer: Rong (EGTRWsdMDR)" ma.framework |
- 给可执行文件执行权限 (chmod +x WeChat)
- 删除Plugins文件夹
- Watch也没办法重签名 直接删除
- 然后执行运行Demo到手机上就行了
脚本自动化重签名
- xcode demo能运行手机上
- 把下面脚本copy到 TRAGETS/Bunild Phases 点击+新建一个Shell script ,然后copy里面
- 先编译下,把ipa放工程下的App文件夹中就行
- 直接运行到手机上了
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 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
#------------------------------ #变量 # ${SRCROOT} xcode工程路径 # $BUILT_PRODUCTS_DIR工程的products路径 # $TARGET_NAME target路径 # $PRODUCT_DUNDLE_IDENTIFIER 当前工程下的bundleID # $EXPANDED_CODE_SIGN_IDENTITY 当前工程下的证书 #------------------------------ #资源路径 RESOURCE_PATH="${SRCROOT}/App" TARGET_IPA_PATH="$RESOURCE_PATH/*.ipa" TEMP_PATH="${SRCROOT}/Temp" #文件夹创建 rm -rf "$TEMP_PATH" mkdir -p "$TEMP_PATH" mkdir "$RESOURCE_PATH" #------------------------------ #1.解压ipa到Temp/ unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH" #2.获取解压后的Temp/Payload/target.app (比如target就是你的.app名) TEMP_PAYLOAD_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app; echo "$1") #------------------------------ #3.获取garget/Demo.app TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app" echo "ppppppppp= $TARGET_APP_PATH" #4.删除Demo中的.app 也就是3步的.app 后重建 rm -rf "$TARGET_APP_PATH" mkdir -p "$TARGET_APP_PATH" #5.将2步的解压后的target.app下的所以内容 copy到工程下Products下(就是替换Demo.app为target.app) cp -rf "$TEMP_PAYLOAD_APP_PATH/" "$TARGET_APP_PATH" #------------------------------ #6.删除Extention和WatchApp(个人证书不能签名Extention) rm -rf "$TARGET_APP_PATH/PlugIns" rm -rf "$TARGET_APP_PATH/Watch" #7.修改Plist的bundleID (xcode中的plist右键选择None 可以看到它真实的名字CFBundleIdentifier) #用/usr/libexec/PlistBuddy工具 用法 "Set KEY Value" "目标文件路径" /usr/libexec/PlistBuddy -c "Set CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_PATH/Info.plist" #------------------------------ #8.给Macho增加执行权限 #获取macho文件 路径 APP_Macho_BINARY=`plutil -convert xml1 -o - $TARGET_APP_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<` chmod +x "$TARGET_APP_PATH/$APP_Macho_BINARY" #------------------------------ #9.重签名第三方的Frameworks (把里面所有的framework循环重签名) TARGET_APP_FRAMEWORKS_PATH="$TARGET_APP_PATH/Frameworks" # 不是所有的App都有FrameWork if [ -d "$TARGET_APP_FRAMEWORKS_PATH"]; then for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"* do #强制签名 /usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK" done fi |