天天看点

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

签名机制

  • 1. 加密解密
    • 1.0 学习流程图
    • 1.1 学前须知
      • 1.1.1 发送消息流程
      • 1.1.2 如何防止被窃听
      • 1.1.3 如何加密解密
      • 1.1.4 密码的类型
      • 1.1.5 密码的配送问题
    • 1.2 对称密码
      • 1.2.1 DES(Data Encryption Standard)
      • 1.2.2 3DES
      • 1.2.3 AES(Advanced Encryiption Standard)
    • 1.3 公钥密码
      • 1.3.1 公钥密码简介
      • 1.3.2 解决密钥配送问题
      • 1.3.3 混合密码系统
        • 1.3.3.1 混合密码-加密
        • 1.3.3.2 混合密码-解密
    • 1.4 单向散列函数
      • 1.4.1 单向散列函数简介
      • 1.4.2 如何防止数据被篡改
      • 1.4.3 单项散列函数的应用-口令加密
  • 2. 数字签名
    • 2.1 数字签名
    • 2.2 数字签名的过程
    • 2.3数字签名的疑惑和无法解决的问题
  • 3. 证书
    • 3.1 证书的简介
    • 3.2 证书的利用
  • 4. IOS签名机制
    • 4.1 签名简介
    • 4.2 IOS签名流程
    • 4.3 IOS签名机制-AppStore
    • 4.4 重签名步骤
      • 4.4.1 常用指令介绍
      • 4.4.2 指令示例
      • 4.4.3 重新签名的GUI工具
      • 4.4.4 tweak原理分析
      • 4.4.5 动态库的注入
      • 4.4.6 更改动态库的加载地址
      • 4.4.7重签名的注意点

1. 加密解密

  • encrypt

    :加密
  • decrypt

    :解密
  • plaintext

    :明文
  • ciphertext

    :密文

1.0 学习流程图

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.1 学前须知

1.1.1 发送消息流程

  • 为了便于学习,设计4个虚拟人物
    • Alice、Bob:互相通信
    • Eve: 窃听者
    • Mallory:主动攻击者
      IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
      IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.1.2 如何防止被窃听

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.1.3 如何加密解密

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.1.4 密码的类型

  • 根据密钥的使用方法,可以将密码分为2种
    • 对称密码
    • 公钥密码(非对称密码)
      IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.1.5 密码的配送问题

  • 在使用对称密码时,一定会遇到密钥配送问题
  • 假设, Alice将

    使用对称密码加密过的消息

    发给了Bob
    • 只有将密钥发送给Bob,Bob才能完成解密
    • 在发送密钥的过程中,可能会被Eve窃取密钥,最后Eve也能完成解密
      IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 如何解决密钥配送问题
    • 事先共享密钥
    • 密钥分配中心
    • Diffie-Hellman密钥交换
    • 公钥密钥

1.2 对称密码

  • 在对称密码中,加密、解密时使用的是同一个密钥
  • 常见的对称密钥算法有:

    DES、3DES、AES

    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.2.1 DES(Data Encryption Standard)

  • DES是一种将64bit明文加密成64bit密文的对称密码算法,密钥长度是56bit
  • 规格上来说,密钥长度是64bit,但是每隔7bit会设置一个用于错误检查的bit,因此密钥长度实质上是56bit
  • 由于DES每次只能加密64bit的数据,遇到比较大的数据,需要对DES加密进行迭代(反复)
  • 目前已经可以在短时间内被破解,所以不建议使用
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.2.2 3DES

  • 3DES,将DES重复3次所得到的一种密码算法,也叫做3重DES
  • 目前还被一些银行等机构使用,但是处理速度不高,安全性逐渐暴露出问题
  • 3个密钥都是不同的,也称为DES-EDE3
  • 如果所有的密钥都使用同一个,则结果与普通的DES是等价
  • 如果密钥1、密钥3相同,密钥2不同,称为DES-EDE2
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.2.3 AES(Advanced Encryiption Standard)

  • 取代DES称为新标准的一种对称密码算法
  • 在2000年时选择Rijindael算法作为AES的实现
  • 目前AES,已经逐步取代DES、3DES,成为首选的对称密码算法
  • 一般来说,我们也不应该去使用任何自制的密码算法,而是应该使用AES,它经过了全世界密码学家所进行的高品质验证工作

1.3 公钥密码

1.3.1 公钥密码简介

  • 公钥密码中,密钥分为

    加密密钥、解密密钥

    2种,它们并不是同一个密钥
  • 公钥密码也被称为

    非对称密码

    (Asymmetric Cryptography)
  • 在公钥密码中
    • 加密密钥,一般是公开的,因此该密钥称为公钥(public key)
    • 解密密钥,由消息接受者自己保管,不能公开,因此也称为私钥(private key)
    • 公钥和私钥是一一对应的,是不能单独生成的,一对公钥和密钥统称为密钥对(key pair)
    • 由公钥加密的密文,必须使用与该公钥对应的私钥才能解密
    • 由私钥加密的密文,必须使用与私钥对应的公钥才能解密
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.3.2 解决密钥配送问题

  • 由消息的接受者,生成一对公钥、私钥
  • 将公钥发给消息的发送者
  • 消息的发送者使用公钥加密消息
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.3.3 混合密码系统

  • 对称密码的缺点: 不能很好的解决密钥配送问题
  • 公钥密码的缺点: 加密解密速度比较慢
  • 混合密码系统,是将对称密码和公钥密码的优势结合的方法
    • 解决了公钥密码速度慢的问题
    • 并通过公钥密码解决了对称密码的密钥配送问题
  • 网络上的密码通信所用的SSL/TLS都运用了混合密码系统

1.3.3.1 混合密码-加密

  • 会话密钥(session key)
    • 为本次通信随机生成的临时密钥
    • 作为对称密码的密钥,用于加密消息,提高速度
  • 加密步骤(发送消息)
    • 首先,消息发送者要拥有消息接受者的公钥
    • 生成会话密钥,作为对称密码的密钥,加密消息
    • 用消息接受者的公钥,加密会话密钥
    • 将前2步生成的加密结果,一并发给消息接受者
  • 发送出去的内容包括
    • 用会话密钥加密的消息(加密方法:对称密码)
    • 用公钥加密的会话密钥(加密方法:公钥密钥)
      IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.3.3.2 混合密码-解密

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.4 单向散列函数

1.4.1 单向散列函数简介

  • 单向散列函数,可以根据消息内容计算出散列值
  • 散列值的长度和消息的长度无关,无论消息是bit、10M、100G,单向散列函数都会计算出固定长度的散列值
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 单向散列函数的特点
    • 根据任意长度的消息,计算出固定长度的散列值
    • 计算速度快,能快速计算出散列值
    • 消息不同,散列值也不同
    • 具备单向性
      IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 单向散列函数,又被称为消息摘要函数(message digest function),哈希函数
  • 输出的散列值,也被称为消息摘要(message digest)、指纹(fingerprint)
  • 常见的几种单向散列函数
    • MD4、MD5:产生128bit的散列值,MD就是 Message Digest的缩写,目前已经不安全,Mac终端默认可以使用MD5命令
    • SHA-1: 产生160bit的散列值,目前已经不安全
    • SHA-2: SHA-256、SHA-384、SHA-512,散列值长度分别为256bit、384bit、512bit
    • SHA-3: 全新标准

1.4.2 如何防止数据被篡改

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

1.4.3 单项散列函数的应用-口令加密

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

2. 数字签名

  • 想象一下场景
    • Alice发的内容有可能是被篡改的,或者有人伪装成Alice发消息,或者就是Alice发的,但她可以否认
    • 问题来了: Bod如何确定这段消息的真实性?如何识别篡改、伪装、否认?
    • 解决方案: 数字签名

2.1 数字签名

  • 在数字签名中,有一下两种行为:
    • 生成签名: 由消息的发送者完成,通过

      签名密钥

      生成
    • 验证签名: 由消息的接受者完成,通过

      验证密钥

      验证
  • 思考: 如何保证这个签名是消息发送者自己签的?
    • 答案:用消息发送者的私钥进行签名
      IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

2.2 数字签名的过程

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

上述签名过程有一个不好的地方就是 ,既需要把明文发送过去,还要把加密之后的密文发送过去,这样可能造成传输的数据有点大

  • 签名过程改造:
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 数字签名其实就是将公钥密码反过来使用
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

2.3数字签名的疑惑和无法解决的问题

  • 思考一下:
    • 如果有人篡改了文件的内容或则签名内容,会是什么结果?
    • 结果是:签名验证失败。证明内容被篡改
  • 数字签名不能保证机密性: 数字签名的作用不是为了保证机密性,仅仅是为了能够识别内容有没有被篡改
  • 数字签名的作用:确认消息的完整性、识别消息是否被篡改、防止消息发送人否认
  • 数字签名无法解决的问题:
  • 要正确使用签名,前提是

    用于验证签名的公钥必须属于真正的发送者

  • 如果遭遇了中间人攻击,那么

    公钥将是伪造的、数字签名将失败

  • 所以在验证签名之前,首先得验证公钥的合法性
  • 那么如何验证公钥的合法性?

    证书

    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

3. 证书

3.1 证书的简介

  • 证书,联想的是驾驶证、毕业证、英语四六级证等等,都是由权威机构认证的
  • 密码学中的证书,全称叫

    公钥证书(Public-key Certificae, PKC)

    ,跟驾驶证类似
    • 里面有姓名、邮箱等个人信息,以及此人的公钥
    • 并由机构认证(Certificate Authority, CA)施加数字签名
  • CA就是能够认定公钥确实属于此人并能够生成数组签名的个人或者组织
    • 有国际性组织、政府设立的组织
    • 有通过提供认证服务来盈利的企业
    • 个人也可以成立认证机构

3.2 证书的利用

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 证书的下载和注册
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

4. IOS签名机制

4.1 签名简介

  • IOS签名机制的作用: 保证安装到手机用户上的app都是经过Apple官方允许的
  • 不管是真机调试,还是发布APP,开发者都需要进过一系列复杂的步骤
    • 生成

      CertificteSingingRequest.certSingingRequest

      文件
    • 获取

      ios_development.cer\ios_distribution.cer

      证书文件
    • 注册device、添加App ID
    • 获取

      *.moblieprovision

      文件
  • 对于真机调试,现在的Xcode已经自动帮助开发者做了以上操作

我们在真机编译一个app,可以看到编译操作中一个操作是签名:

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

4.2 IOS签名流程

  • 使用apple的私钥,便于Apple的对app的控制
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 生成Mac设备的公私钥:

    CertificteSingingRequest.certSingingRequest

    文件就是Mac设备的公钥
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 获取证书:把Mac的公钥上传到Apple的服务器,然后Apple使用自己

    私钥签名

    生成一个证书给我们该步骤对应着流程图的②步骤
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 获取证书:

    ios_development.cer\ios_distribution.cer

    利用Apple后台私钥,对Mac设备的公钥进行签名后的证书文件
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 生成

    moblieprovision

    文件
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

4.3 IOS签名机制-AppStore

  • 如果APP是从AppStore下载安装的,你会发现里面是没有

    moblieprovision

    文件的
  • 它的验证流程会简单很多,大概如下所示
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

4.4 重签名步骤

4.4.1 常用指令介绍

  • 签名被破坏的app是不能安装到用户的手机上
  • 准备一个

    embedded.mobileprovision

    文件(必须是付费证书产生的,appid、device定需要匹配),并放入

    .app

    包中
    • 可以通过Xcode自动生成,然后再编译后的APP包中找到
    • 可以去开发者证书网站生成下载
  • embedded.mobileprovision

    文件中提取出的

    entitlements.plist

    权限文件
    • security cms -D -i embedded.mobileprovision > temp.plist

    • /usr/libexec/PlistBuddy -x -c 'Print :Entitlements' temp.plist > entitlements.plist

  • 查看可用的证书
    • security find-identity -v -p codesigning

  • .app

    内部的动态库、AppExtension等进行签名
    • codesign -fs 证书ID xxx.dylib

  • .app

    包进行签名
    • codesign -fs 证书ID --entitlements entitlements.plist xxx.app

    • codesign -f -s 证书ID --entitlements entitlements.plist xxx.app

4.4.2 指令示例

  • 我们可以在终端上直接输入

    codesign

    查看该指令的一些用法,如果

    codesign或则codesign --help

    无法看到详细的介绍, 那么可以使用

    man codesign

    来查看详细的用法
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 查看可用证书
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 获取

    entitlements.plist

    文件,然后替换

    .app

    包内的这个文件
    • 该文件内包含与app匹配的

      Bundle identifier

      信息
    • 该文件必须有你需要安装该app的

      device

      的信息
  • 抽取

    entitlements.plist

    文件
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

4.4.3 重新签名的GUI工具

  • IOS App Signer
    • https://github.com/DanTheMan827/ios-app-signer
    • 可以对

      .app

      重新签名打包成ipa
    • 需要再

      .app

      包中提供对应的

      embedded.mobileprovision

      文件
  • iReSign
  • https://github.com/maciekish/iReSign
  • 可以对

    ipa

    进行重签名
  • 需要提供

    entitlements.plist、embedded.mobileprovision

    文件的路劲

4.4.4 tweak原理分析

  • 我们编译好的

    tweak

    代码编写好,是动态库的形式安装到手机上, 当我们手机app启动时,会去

    Devcie/Library/MobileSubstrate/DynamicLibraries

    路径下去加载对应的

    tweak动态库

    , 如果我想把我们编辑好的插件工程安装到别的手机上, 那么我们应该讲这个

    tweak动态库

    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 接下来将我们的

    .app

    包拷贝出来,然后将我们的编写的

    tweak

    动态库也放到

    .app

    的包中
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

也可以通过MachOview来查看可执行文件会加载的动态库

IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 然后再对我们的app包进行重签名,但是启动app的时候会加载我们的动态库吗?,我们可以通过指令去查看

    可执行文件

    依赖的动态库
  • 是不会加载的, 我们需要自己更改动态库的加载地址,让可执行文件加载的时候会加载这个动态库,这个时候我们需要在Mach-O文件插入我们自己的动态库(动态库是插入到LoadCommands 最后一条信息后面,不然会改变其它数据的位置)

4.4.5 动态库的注入

  • 可以使用

    insert_dylib

    库将动态库注入到Mach-O文件中
    • https://github.com/Tyilo/insert_dylib
  • 用法
    • insert_dylib 动态库加载路劲 Mach-O文件

    • 有两个常用参数选项:
      • --weak

        :即使动态库找不到也不会报错,如果不使用这个参数,把动态库注入到Mach-O文件中,app启动的时候,如果找不到动态库的路径,那么app就回崩溃
      • --all-yes

        :后面所有的选择都没yes
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 可以通过otool查看Mach-O的动态库依赖信息
    • otool -L Mach-O文件
      IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 如果不希望生成新的文件
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

4.4.6 更改动态库的加载地址

  • 可以使用

    install_name_tool修改Mach-O文件动态库中的加载地址

    • install_name_tool -change 旧地址 新地址 Mach-O文件

  • 通过Theos开发的动态库插件(dylib)
    • 默认都依赖于

      /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate

    • 如果将要动态库插件打包到

      ipa

      中,也需要将

      CydiaSubstrate

      打包到

      ipa

      中,并且修改下

      CydiaSubstrate

      的加载地址
  • 两个常用的环境变量
    • @executable_path

      :代表可执行文件所在的目录
    • @loader_path

      :代表动态库所在的目录
  • 利用插件来修改ipa包,然后重签名步骤
    1. 往Mach-O文件内注入动态加载
    2. 把动态库依赖的动态库路径的修改
    3. 重新签名 (给动态库进行签名)
    4. 然后再对

      .app

      包进行签名
  • 动态库中也会依赖其它动态库
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 使用指令更换动画库的路径
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制
  • 对动态库进行重签名
    IOS逆向学习-签名机制1. 加密解密2. 数字签名3. 证书4. IOS签名机制

4.4.7重签名的注意点

  • 如果希望将破坏了签名的安装包,安装到非越狱的手机上,需要对安装包进行重签名的操作
  • 注意
    • 安装包中的可执行文件必须是脱壳的,重签名才会有效
    • .app

      包内部的所有动态库(.framework、.dylib)、AppExtension(PlugIns文件夹,拓展名appex)、WatchApp(Watch文件夹)都需要重新签名
  • 重新签名打包后,安装到设备的过程中,可能需要经常查看设备的日志信息
    • 程序运行过程中:

      Window -> Devices and Simulators -> View Device Logs

    • 程序安装过程中:

      Window -> Devices and Simulators -> Open Console