Open ShannonChenCHN opened 7 years ago
下载 cartool 源码;
打开 project,Command+B 编译一下;
找到工程目录 products 下的 cartool 文件,右击,show in finder;
$ cd <cartool文件所在目录>
$ ./cartool /xxx/Assets.car /xxx/outputDirectory
class-dump
/usr/bin
目录的访问权限:重启电脑按住 cmd+R
,打开终端,输入 csrutil disable
。class-dump
可执行文件到 /usr/bin
目录下class-dump
操作权限:执行 sudo chmod 777 /usr/bin/class-dump
命令class-dump -H 要破解的可执行文件路径 -o 破解后的头文件存放路径
示例脚本:
#!/usr/bin/env bash
TABLENAME=symbols
SYMBOL_DB_FILE="symbols"
STRING_SYMBOL_FILE="func.list"
HEAD_FILE="$PROJECT_DIR/$PROJECT_NAME/codeObfuscation.h"
export LC_CTYPE=C
#维护数据库方便日后作排重
createTable()
{
echo "create table $TABLENAME(src text, des text);" | sqlite3 $SYMBOL_DB_FILE
}
insertValue()
{
echo "insert into $TABLENAME values('$1' ,'$2');" | sqlite3 $SYMBOL_DB_FILE
}
query()
{
echo "select * from $TABLENAME where src='$1';" | sqlite3 $SYMBOL_DB_FILE
}
ramdomString()
{
openssl rand -base64 64 | tr -cd 'a-zA-Z' |head -c 16
}
rm -f $SYMBOL_DB_FILE
rm -f $HEAD_FILE
createTable
touch $HEAD_FILE
echo '#ifndef Demo_codeObfuscation_h
#define Demo_codeObfuscation_h' >> $HEAD_FILE
echo "//confuse string at `date`" >> $HEAD_FILE
cat "$STRING_SYMBOL_FILE" | while read -ra line; do
if [[ ! -z "$line" ]]; then
ramdom=`ramdomString`
echo $line $ramdom
insertValue $line $ramdom
echo "#define $line $ramdom" >> $HEAD_FILE
echo "#define _$line _$ramdom" >> $HEAD_FILE
fi
done
echo "#endif" >> $HEAD_FILE
sqlite3 $SYMBOL_DB_FILE .dump
- 生成密钥(这个 key 只有发送方和接收方知道)
- 加密:调用时,发送方,组合各个参数用密钥 key按照一定的规则(各种排序,MD5,ip等)生成一个access_key,一起提交到API接口
- 校验:接收方拿到post过来的参数以及这个access_key。也和发送一样,用密钥key 对各个参数进行一样的规则(各种排序,MD5,ip等)也生成一个access_key2
- 对比access_key 和access_key2 。一样。则允许操作,不一样,报错返回或者加入黑名单
只有在越狱之后,iOS 才能运行没有签名的代码。 越狱使应用可以绕过代码签名和沙盒安全机制的全部限制,这会是一个非常危险的行为。
作为一个 iOS 开发者,在你开发使用的机器上应该已经有一个证书,一个公钥,以及一个私钥。这些是代码签名机制的核心。
有两种方式可以查看你的系统中能用来对代码进行签名的证书:
security find-identity -v -p codesigning
$ csapp security find-identity -v -p codesigning
1) A853191D0F53EBEEAADD9EE99932CA596F5A1F9F "Mac Developer: 273879688@qq.com (C6KU79QV5A)"
2) 8120BD6A4536DCF46DBBF7D88EFF9EAB241F1870 "iPhone Developer: 273879688@qq.com (C6KU79QV5A)"
2 valid identities found
一个证书是一个公钥加上许多附加信息,这些附加信息都是被某个认证机构(Certificate Authority 简称 CA)进行签名认证过的,认证这个证书中的信息是准确无误的。
签名过程本身是由命令行工具 codesign 来完成的。如果你在 Xcode 中编译一个应用,这个应用构建完成之后会自动调用 codesign 命令进行签名。
一个已签名的可执行文件的签名包含在 Mach-O 二进制文件格式中。
在 macOS 和 iOS 上的任何可执行二进制文件都可以被设置签名:不论是动态库,命令行工具,还是 .app
后缀的程序包。
设置签名的过程实际上会改动可执行文件的文件内容,将签名数据写入二进制文件中。
如果你拥有一个证书和它的私钥,那么用 codesign 来设置签名非常简单:
$ codesign -s "iPhone Developer: 273879688@qq.com (C6KU79QV5A)" ~/Desktop/AwesomeProject.app
/Users/ShannonChen/Desktop/AwesomeProject.app: is already signed
为一个已经签过名的文件重新签名:
$ codesign -f -s "iPhone Developer: 273879688@qq.com (C6KU79QV5A)" ~/Desktop/AwesomeProject.app
/Users/ShannonChen/Desktop/AwesomeProject.app: replacing existing signature
查看文件签名状态的信息:
$ codesign -vv -d ~/Desktop/AwesomeProject.app
得到的结果:
Executable=/Users/ShannonChen/Desktop/AwesomeProject.app/AwesomeProject
Identifier=org.reactjs.native.example.AwesomeProject
Format=app bundle with Mach-O thin (x86_64)
CodeDirectory v=20400 size=55629 flags=0x0(none) hashes=1731+3 location=embedded
Signature size=4799
Authority=iPhone Developer: 273879688@qq.com (C6KU79QV5A)
Authority=Apple Worldwide Developer Relations Certification Authority
Authority=Apple Root CA
Signed Time=2019年2月15日 下午4:19:35
Info.plist entries=29
TeamIdentifier=L32PN8QKLZ
Sealed Resources version=2 rules=13 files=12
Internal requirements count=1 size=208
检查一下封印是否完好,没有任何输出说明签名是完好的:
$ codesign --verify ~/Desktop/AwesomeProject.app
为一个程序包设置签名时,这个包中的所有资源文件也都会被设置签名,包括图片、XIB/NIB 文件、存档文件(archives),甚至是证书文件。
为了达到为所有文件设置签名的目的,签名的过程中会在程序包中新建一个叫做 _CodeSignatue/CodeResources 的文件,这个文件实际上是一个 xml 文件,其中定义了被签名的程序包中所有文件的签名。
<?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>
<key>files</key>
<dict>
...
</dict>
<key>files2</key>
<dict>
<key>Base.lproj/LaunchScreen.nib</key>
<dict>
<key>hash</key>
<data>
hTT3EydgxVsF1sYscxcv10yz+kw=
</data>
<key>hash2</key>
<data>
u2MAOaedOTTaTtvI7WSWhH5swfkntlTSa1izuXC50Jk=
</data>
</dict>
...
</dict>
<key>rules</key>
<dict>
...
</dict>
<key>rules2</key>
<dict>
...
</dict>
</dict>
代码签名保证了这个应用里所包含的内容没有被修改过,而沙盒则是限制了应用访问系统的资源。
授权机制决定了哪些系统资源在什么情况下允许被一个应用使用。简单的说它就是一个沙盒的配置列表,上面列出了哪些行为被允许,哪些会被拒绝。
在 Xcode 的 Capabilities 选项卡下选择一些选项之后,Xcode 会自动生成一个 .entitlements
文件,然后在需要的时候往里面添加条目。当构建整个应用时,这个文件也会提交给 codesign 作为应用所需要拥有哪些授权的参考。这些授权信息必须都在开发者中心的 App ID 中启用,并且包含在配置文件中。
授权信息会被包含在应用的签名信息中,你可以尝试查看签名信息中具体包含了什么授权信息:
$ codesign -d --entitlements - AwesomeProject.app
一个描述文件是一组信息的集合,这组信息决定了某一个应用是否能够在某一个特定的设备上运行。
一个证书可以对应多个不同的描述文件。
如果你要在自己的机器上找到描述文件,在这个目录下 ~/Library/MobileDevice/Provisioning Profiles
,Xcode 将从开发者中心下载的全部描述文件都放在了这里。
描述文件是一个根据密码讯息语法 (Cryptographic Message Syntax) 加密的文件,在 Mac 上不能直接打开查看,不过我们可以用 security 工具查看描述文件中的信息:
$ security cms -D -i ~/Library/MobileDevice/Provisioning\ Profiles/c1f2bcb3-6e73-4db8-abc7-260eef7f904c.mobileprovision
<?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>
<key>AppIDName</key>
<string>onlyu</string>
<key>ApplicationIdentifierPrefix</key>
<array>
<string>38K2TJBGY2</string>
</array>
<key>CreationDate</key>
<date>2016-11-24T04:34:48Z</date>
<key>Platform</key>
<array>
<string>iOS</string>
</array>
<key>DeveloperCertificates</key>
<array>
<data>MIIFjDCCBHSgAwIBAgIIedRPpOc4HBIwDQYJKoZIhvcNAQEFBQAwgZYxCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBsZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBwbGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTYxMTI0MDQyMTQ4WhcNMTkxMTI0MDQyMTQ4WjCBjTEaMBgGCgmSJomT8ixkAQEMCjM4SzJUSkJHWTIxMDAuBgNVBAMMJ2lQaG9uZSBEaXN0cmlidXRpb246IFlIT1VTRSBDb3Jwb3JhdGlvbjETMBEGA1UECwwKMzhLMlRKQkdZMjEbMBkGA1UECgwSWUhPVVNFIENvcnBvcmF0aW9uMQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALmEtQvnT7HgEPrNctaIZkE5UVpHby+BwkcdcYUJpOEa4hgYjEKGQEm6kCCjaITygndAMLl9aa+uj7YXRZoTkIZI1GihaqfWfw0lpMrAWnRc2R6BEEQTpnu0+iEvIoqyXG49WW6jSpFok2Lk3kCFOCvKRauvm7QyvIM13t++wcujtATn4pVUGJ7sIIFDM3QPTwLrwA89n6EQb/14KWdk0I0U72gKeNXGYj2TNiT+qOpD94GCTyPSRCgN8xUL8FZQZQ/8cw9ZAwrHhO8h7tSpjEQr1VhdYrIYu4cBwpekANzDjZ+jDwld+WIra8wiETfoFvGgktQIkqx7glNeilITUCUCAwEAAaOCAeMwggHfMD8GCCsGAQUFBwEBBDMwMTAvBggrBgEFBQcwAYYjaHR0cDovL29jc3AuYXBwbGUuY29tL29jc3AwMi13d2RyMDEwHQYDVR0OBBYEFL7srqri6AwTjTOt0lKhQFNFKWYxMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUiCcXCam2GGCL7Ou69kdZxVJUo7cwggEPBgNVHSAEggEGMIIBAjCB/wYJKoZIhvdjZAUBMIHxMIHDBggrBgEFBQcCAjCBtgyBs1JlbGlhbmNlIG9uIHRoaXMgY2VydGlmaWNhdGUgYnkgYW55IHBhcnR5IGFzc3VtZXMgYWNjZXB0YW5jZSBvZiB0aGUgdGhlbiBhcHBsaWNhYmxlIHN0YW5kYXJkIHRlcm1zIGFuZCBjb25kaXRpb25zIG9mIHVzZSwgY2VydGlmaWNhdGUgcG9saWN5IGFuZCBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVudHMuMCkGCCsGAQUFBwIBFh1odHRwOi8vd3d3LmFwcGxlLmNvbS9hcHBsZWNhLzAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwMwEwYKKoZIhvdjZAYBBAEB/wQCBQAwDQYJKoZIhvcNAQEFBQADggEBACCsQ85W+jGC9Cl7LuNq3aW00UVJJcjIWEF0cXborTL9nP6oDlKv4cmSSrEVwSYm94pDoslFpPErwwGySvILxJ7yo7D3YA3myN06w67iFSioZlh28xMcCTdB3UnMKr2A8hw0mwMRY91PzhU6zKGgCCQ3IhzTtxZAZMVXGyjHFQMcQMR6tOGSHzdBNfaJ/aKfZ2OKuQk4IJlF01JF42mmNHMC/G6bfZzWVFPzDZ4O7Mq6jKzb9tb6yLEnIZwugqLfGt9fKWX9fq380IdgrNEuQf4iBb07kgBoADQjYNDXkzOVV3/ml/TuD68xetE7UG5zfNtd490G9WMgI6Mk7ffWhs8=</data>
</array>
<key>Entitlements</key>
<dict>
<key>keychain-access-groups</key>
<array>
<string>38K2TJBGY2.*</string>
</array>
<key>get-task-allow</key>
<false/>
<key>application-identifier</key>
<string>38K2TJBGY2.com.yhouse.onlyu</string>
<key>com.apple.developer.team-identifier</key>
<string>38K2TJBGY2</string>
<key>aps-environment</key>
<string>production</string>
</dict>
<key>ExpirationDate</key>
<date>2017-11-24T04:34:48Z</date>
<key>Name</key>
<string>onlyu_inHouse_distribution</string>
<key>ProvisionsAllDevices</key>
<true/>
<key>TeamIdentifier</key>
<array>
<string>38K2TJBGY2</string>
</array>
<key>TeamName</key>
<string>YHOUSE Corporation</string>
<key>TimeToLive</key>
<integer>365</integer>
<key>UUID</key>
<string>c1f2bcb3-6e73-4db8-abc7-260eef7f904c</string>
<key>Version</key>
<integer>1</integer>
</dict>
</plist>%
跟我们平时签合同一样,代码签名主要保证两点:
好处:
局限:
创建 iOS 开发/发布证书的第一步就是 Certificate Signing Requests。
CSR 请求指的是申请者为了申请一个数字身份证书(digital identity certificate)而向权威认证机构发送一条信息。
创建 CSR 请求的过程是 PKI(Public Key Infrastructure)中的一个标准,在这个过程中,申请者要在本地的机器上生成一对公钥和私钥。申请者会将公钥、邮箱地址、国家等信息附加到 CSR 中,私钥会由申请者自己保留起来。
创建一个 CSR 请求通常需要以下这些信息:
向苹果发送 CSR 请求时,苹果会验证请求信息,如果验证通过,就会分发证书。
CSR 请求的发起必须是在 macOS 机器上,发送 CSR 请求有两种方式:
在我们创建 CSR 文件时,发生了这几件事:
根据官方文档,苹果总共有 10 种不同类型的证书。
创建证书的步骤:
.cer
证书,可以下载下来双击下载下来的 .cer
证书,系统就会自动将它添加到 KeyChain 中。Keychain 会自动把它和之前创建 CSR 时自动生成的私钥归为一组,无论是在「我的证书」中查看证书还是在「密钥」中查看私钥,都能看到与之匹配的另一半。
当我们想要在另一台机器上上进行代码签名时,据需要将公钥证书和对应的私钥导出成一个 .p12
文件。
.p12
文件是根据 PKCS#12 标准生成的,PKCS#12 是一种公钥密码学标准(Public Key Cryptography Standard,PKCS)。这个标准用来将私钥和公钥证书保存成一个文件,并用密码保护起来。
.p12
文件中包含我们的公钥证书和对应的私钥,我们可以用下面的命令查看 .p12
文件中的信息:
$ openssl pkcs12 -info -in mycert.p12
Provisioning Profile 实际上是证书、app ID、device ID 和 entitlements 的组合。
注:从 Xcode 8 开始,苹果推出了 automatic code signing 机制,可以自动创建和管理 Provisioning Profiles。
手动创建 Provisioning Profile 的步骤:
双击下载好的 Provisioning Profile 后,系统会自动将其添加到 ~/Library/MobileDevice/Provisioning\ Profiles
目录下。
在 Xcode 的 General tab 中可以选择是否开启 Automatically manage sigining
,在未开启 Automatically manage sigining
的模式下,可以在 Build Settings tab 中手动指定 Provisioning Profile。
Xcode 的自动签名只适合在本地机器上使用,如果需要在 CI 服务器上签名就需要自己去执行脚本调用相关工具进行手动签名了。
苹果提供了一个叫做 codesign 的命令行工具来进行手动签名,Xcode 的自动签名机制其实本质上也是在调用这个命令行工具。
对 iOS App 签名时,会经历这三个步骤:
代码签名软件用签名者的身份信息生成数字签名来对 seal 进行编码,以保证密封的完整性。
Code Requirement 是验证代码签名时的规则。
准备条件:
重签名步骤:
.ipa
_CodeSignature
目录(图片来源:http://xelz.info/blog/2019/01/11/ios-code-signature/)
(图片来源:http://blog.cnbang.net/tech/3386/)
TLS/SSL 握手过程(单向认证)
完整的 HTTPS 连接的建立过程
延伸阅读: