逆向破解5 - ios的签名机制和ios平时用的算法原理

前情回顾:
为什么要了解ios的签名机制:
目前我所了解的逆向的方法有:一个就是用tweak的方法来进行hook oc的代码,另一个就是将oc的可执行文件修改了,然后在重新签名装到手机上。

怎样修改oc的可执行文件

比如我写个ios的代码,他的主要是意思就是弹出一个弹框

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    [self showAlertView];
    
}
- (void)showAlertView{
    UIAlertController *alertVc = [UIAlertController alertControllerWithTitle:@"提示" message:@"asdasdasd" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
    [alertVc addAction:okAction];
    [self presentViewController:alertVc animated:YES completion:nil];
}

我们找到他的可执行文件(前面文章有介绍,这里不再赘述了,这里说一下大致的步骤)

MJAppTools -l AlertDemo

找到位置为:

 /private/var/containers/Bundle/Application/C29FF3E4-23DD-48CF-8D2A-02F73657ADC6/alertDemo.app
  /private/var/mobile/Containers/Data/Application/D7CD11FF-A97F-46F0-B641-55F7E40EB274

假设我们经过一段自己的分析找到了我们的hopper中代码执行片段


image.png

经过我们前几天学习汇编指令,删除这段他就不会出现提示了


image.png

点击这样的操作:
image.png

最后变为:


image.png

可以看到调用的代码变为空了。然后我们在重新生成可执行文件
image.png

在将我们重新生成的可执行文件覆盖我们之前手机的可执行文件
image.png

然后运行我们的app可以看到并没有出现弹框了.
注意点:
1.目前我是用xcode运行但是正常安装到手机上的都需要脱壳的。

2.目前我们这种方式都是安装到自己的手机,如果安装到别人的手机将我们这一坨整理一下生成一个ipa是装不到别人的手机,因为他需要重新对可执行文件重新签名。要想完全弄懂签名我们需要首先了解一些常规的算法原理。

算法相关的

首先我们假设几种环境并且来大致说一下加密的方式,我们现在假设几种情况:A 要发送邮件给 B,其中C是窃听者,D是主动攻击者,那么A
要发送给B,首先他要对他的邮件内容进行加密,加密的话我们首先要设置一个字符串来对我们的明文消息加密生成暗文,然后在发送暗文消息,B接收到暗文之后 B用刚才A加密的那串字符串进行解密,我们把加密明文的字符串叫做密钥。现在按照密钥的加密方式我们大致可以分为两种加密方式:一种是对称加密、一种是公钥加密(非对称加密)

  • 对称加密
    在对称加密过程中,加密和解密用的是同一个密钥也就是私钥,他的大致流程是这样的:


    image.png

    流程描述:
    1.A用密钥进行加密明文生成暗文进行传递
    2.B收到暗文之后用密钥进行解密,获得明文信息。
    缺点:就是密钥配送问题,如果假如A和B是优盘共享密钥的还没有问题,但是生活中或者实际上A和B甚至都不知道对方是谁,所以对称加密的问题最大的问题就是密钥配送问题。
    采用对称加密的算法有:DES 、3DES、 AES

  • DES说明:他是采用了64bit明文加密成64bit暗文的对称密码算法,但是他的密钥长度是56bit,因为其中他每7位有一个错误检查的bit,那样64位正好是检查了8次,所以还剩下56个,但是我们也看到了他是加密64bit比较小那么假如信息量稍微大点就可能需要多次发送。现在一般很少采用这样算法了,因为他比较短时间内就能被破解。
  • 3DES说明:他是DES3次重复加密的结果,大致流程如下:


    image.png

    3DES的流程说明:
    加密过程:

1.将明文用密钥1进行加密生成暗文
2.将1所生成的暗文用密钥2进行解密得到暗文
3.将2所得的暗文用密钥3进行加密生成暗文

解密过程:
1.将传递过来的暗文用密钥3进行解密得到暗文
2.将1得到的暗文用密钥2进行加密得到暗文
3将2得到的暗文用密钥1进行解密得到明文
说明:
1.现在的3DES 有些部分银行还在使用但是还是安全性不高和存在传输内容不能过大的问题。
2.密钥 1、2、3必须是不同的否则和DES加密没有区别了。

  • AES 加密说明:
    1.他是DES的一个升级版,也就是改进了DES的一些缺点
    2.他的长度有128 、192 、256bit的

密钥配送相关

通过刚才的例子说明:密钥可能会被c知道 还有可能会被D进行攻击.
解决密钥配送的方案是:
1.事先共享密钥
2.密钥分配中心 ,就是A和B到这来拿
3.公钥密码
说明以上三种方法最常用的就是公钥密码的方法

公钥密码加密的算法(非对称加密)

首先他的大致流程为:


image.png

流程说明:
1.首先B会自己生成一对公钥和私钥、其中私钥和公钥是成对出现的、公钥可以随便给别人但是私钥要自己留着,这里他会把公钥发给A
2.A用B给的公钥进行加密自己的明文生成暗文发送给B
3.B用自己的私钥进行解密暗文生成明文。
注意点:
1.这样非对称的加密方式很好的解决了密钥配送的问题
2.但是存在的弱点就是如果消息发送频繁那么他的加密解密是需要时间的,所以造成的后果就是传输慢
3.目前采用公钥密码加密是很明显的一个算法就是RSA

混合密码加密

我们知道对称加密有密钥配送问题,公钥密码加密有传输缓慢的缺点,那么现在需要将这两种算法进行结合就能完美的解决问题。假如现在A给B发送消息可知大致这样的流程:
其中解密过程流程图如下:


image.png

解密过程的流程图如下:


image.png
  • 文字说明混合加密过程:
    1.还是有B生成一对公钥和私钥,公钥和私钥是一一对应的。
    2.B加公钥发送给A,A本地随机生成一个会话密钥,用会话密钥加密明文消息。
    3.A用公钥开始加密会话密钥并且将加密后的会话密钥和暗文一起发送给B
  • 文字说明解密过程:
    1.收到A发送过来的加密的会话密钥进行用私钥解密得到会话密钥
    2.将1步所获得会话密钥进行解密暗文,获得明文
    总结:以上既解决了传输慢的问题,因为对称加密传输消息内容,会话密钥采用的是的非对称加密因为会话密钥很小所以很快,这样就完美了。但是我们还是发现存在了一个问题:因为B发的公钥是给A的,B的公钥也可能是给别人,那么别人拿到公钥生成一串信息给B那么B在收到消息的时候怎么知道是A发送过来的呢?为了防止这个问题 我们需要对A发的消息进行签名,要知道签名需要先知道单向散列函数。

单向散列函数

  • 概念:单项散列函数是根据内容计算出一个特定数字的散列值,假如我们的内容就算是100K 、100M 、100G 他生成的也可能都是128 bit 或者256bit等等。而且改变其中的一个字节可能生成的散列值就是千差万别的。
    特点:
    1.具备单向性不可逆的,不能由散列值生成原来的消息。
    2.计算速度快能够很快的计算出散列值。
    3.常见的单向散列函数有MD5 、MD4(128位的)SH1 系列(目前已经不安全了)SH2系列(SHA - 256 、SHA - 384 、SHA - 512 分别对应:256字节、384字节、512字节) SH3(全新的一个标准)
    4.一般来讲生成的散列值越高 破解难度越高 。
  • 应用
    1.账号密码,比如我们用户的密码传递给服务器,每一个密码都是经过加密的一般来说采用的是单向散列函数进行加密,那么服务器存储你的密码也是单向散列函数的散列值,比如是MD5那么数据存储可能是一个32个字母和数字组成的字符串,等你在登录也是重新生成你的密码散列值进行比较看是不是同一个密码。如果假如服务器存储都是你的明文密码或者app找回密码中 直接是将密码返回给你 一般来说都是不安全的。

数字签名

解释:数字签名是为了保证消息发送者一定是本人,这个过程并不能保证消息是安全的,他的大致流程是这样的:


image.png

流程说明:
1.首先A将消息发送给B,B收到消息将消息通过单向散列函数生成一个散列值保存起来。
2.A将消息通过单向散列函数生成一个散列值,将散列值用自己的私钥进行加密(签名)并将签名发送给B
3.B收到签名之后用A给B的公钥进行解密签名解密完签名获得散列值与之前获得散列值进行比较。如果一致则是通一个消息。

  • 数字签名注意点:就是签名的公钥必须是真正的发送者
  • 数字签名无法解决的问题:


    image.png

    他的出现流程是:
    1.A要给B发送消息,B将自己的公钥发送给A,但是这时候被攻击者D窃取到了
    2.D保留了B给A的公钥,并且将自己生成的公钥发送给A,A收到了公钥之后将自己的明文消息进行加密将这个暗文发送给B,这时候又被D获取到了。
    3.D用自己的私钥解密了暗文得到了A发送给B的明文,这时候自己伪造了一份消息将这个消息用B给A的公钥进行加密发送给了B

  1. B拿到了消息以为还是A发过来的暗文并且用自己的私钥也能解开了,他们都以为双方发送正常消息呢但是实际上消息早就被D篡改了并且获得明文消息。
  • 所以必须要验证公钥的合法性,验证公钥的合法性 需要做的就是证书。

证书

概念:证书是由签名机构签发有一定公认性的权威标志。比如可以是一个机构或者政府机构或者某个公司或者其他情况等等办发的权威标志。值得说明的是密码学中的证书全是公钥证书。证书能够做到的事情就是确定此公钥确实属于某个人。
举个简单的例子:


image.png

流程解释:
1.首先是B向A发送公钥确保公钥一定是B的,没有经过中间人攻击过
2.B在权威机构注册将自己的公钥上传给权威机构,一般来说也会上传自己的个人信息
3.权威机构用自己的私钥(一般都是)加密B的公钥并且保存在自己的仓库
4。A从权威机构的仓库中进行下载获得经过私钥加密的B的公钥的密文
5.用权威机构的公钥进行解密获得B的公钥那样就能证明此公钥一定就是B的

苹果证书的一套流程以及每一个步骤的说明

  • 整个流程


    image.png

    整体流程说明:
    1.在发布ipa包的时候用mac私钥进行加密自己的app
    2.首先要从自己的mac电脑上获得mac的公钥也就是CertificateSigningRequest.certSigningRequest
    3.获得ios_development.cer\ios_distribution.cer证书文件
    4.项目的bundle id 还有设备手机获得一个*.mobileprovision文件
    5.获得苹果的公钥进行解密证书获得mac的公钥
    6.验证并且安装到手机

分布流程说明

1.获取mac电脑上的公钥


image.png

其实这个就是获取mac电脑上的公钥
2.获取ios_development.cer\ios_distribution.cer证书文件
这个证书其实就是用苹果自己的私钥对我们上传的CertificateSigningRequest.certSigningRequest进行加密签名生成的
也就是这个步骤:


image.png

3.再次生成一个证书,其中这个证书包含的有项目的buildleID、手机设备的唯一的ID还有一些的权限信息。这个证书叫.mobileprovision文件
对应的是这步:
image.png

image.png

4.这时候我们点击真机调试他首先会:
用苹果的公钥(存在每一个ios设备中)解密获得我们的设备信息和项目id等等进行验证对应于这步:


image.png

5.再次用苹果的公钥获得第一个签名的证书来获取mac的公钥,对应于这步:
image.png

6.此时获得公钥一定就是mac的公钥并且没有人篡改过的,用mac公钥验证签名我们的ipa包对应于这步(因为开始我们的ipa包是经过mac私钥进行签名的):
image.png
  • 注意点:
    1.如果我们是调试的话 那么就没有验证ipa包这一个过程 他走之前那几步就行了
    2.如果是appstore的包用的不是mac的私钥进行签名的ipa包 ,而用的是苹果的私钥进行签名的,所以直接装到手机上就能使用,因为每一个手机都有苹果的公钥。