iOS签名机制

iOS签名机制

加密基础

常见名词

  • encrypy: 加密
  • decrypt: 解密
  • plaintext: 明文
  • ciphertext: 密文

密码的类型

根据密钥的使用方法,可以将密码分为两种

  • 对称密码 Symmetric Cryptography

    • DES (Data Encryption Standard)

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

    • 3DES (加密-解密-加密)

    将DES重复3次(3个不同密钥 DES-EDE3)所得到的一种密码算法,也叫做3重DES
    处理速度不高,安全性也不高
    如果所以密钥都使用一个,则结果和普通DES相同

    • AES (Advanced Encryption Standard)

    取代DES成为新标准的一种对称密码算法

  • 公钥密码(非对称加密) Public-key Cryptography

    • RSA (目前使用最广泛的)

    加密密钥(公钥)一般是公开的,因此该密钥称为公钥 (public key)
    解密密钥(私钥),由消息接收者自己保管的,不能公开,因此也称为私钥(private key)
    公钥和私钥是一一对应的, 是不能单独生成的,一对公钥和密钥统称为密钥对(key pair)
    由公钥加密的密文,必须使用该公钥对应的私钥才能解密

  • 混合密码系统 (Hybrid Cryptosystem)

    使用非对称密钥对对称密钥进行加密,再使用对称密钥对数据加密

    对称密码的缺点,不能很好的解决密钥配送问题
    公钥密码的缺点,加密解密速度比较慢
    混合密码系统,是将对称密码和公钥密码的优势相结合

密钥配送问题

在使用对称密码是,一定会遇到密钥配送问题

  • 事先共享密钥
  • 密钥分配中心
  • Diffe- Hellman密钥交换
  • 公钥密码 (由消息接收者生成一对公钥和私钥, 将公钥发送给消息的发送者,消息发送者通过公钥加密)

单向散列函数 One-way hash function

又被称为摘要函数,哈希函数

输出的散列值,也被称为消息摘要,指纹

特点

  • 单向散列函数可以根据任意长度的消息计算出固定长度的散列值

  • 计算速度快

  • 消息不同,散列值不同

  • 具备单向性

常见的散列函数

  • MD4、MD5

    • 产生128bit的散列值, 目前已经不安全

    • Mac终端默认可以使用md5命令

      1
      2
      md5 1.text
      md5 -s "123"
  • SHA-1

    • 生成160bit的散列值,目前已经不安全
  • SHA-2

  • SHA-256/SHA-384/SHA-512 散列值长度分别是256bit/384bit/512bit

  • SHA-3

    • 全新标准

数字签名

  • 生成签名
    • 由消息发送者完成,通过“签名密钥”(私钥加密) 生成
  • 验证签名
    • 由消息接收者完成,通过“验证密钥”(公钥解密) 验证

如何保证这个签名是消息发送者自己签的

由消息发送者的私钥签名

签名的过程

消息发送者用自己的私钥加密消息,然后将明文和密文发送给接收者。

接收者收到消息用公钥解密密文,对比解密后的消息和明文消息,如果一致则验证通过。

改进的办法:

消息发送者用散列算法将消息计算出散列值,然后将散列值加密,之后将明文和密文发送给接收者。

接收者收到消息用公钥解密出散列值,接收者将明文计算出散列值并对比解密后的散列值,如果一致则验证通过。

证书 (Certificate)

密码学中的证书,全称公钥证书(Public-key Certificate, PKC)

里面有姓名,邮箱等个人信息,以及此人的公钥,并由认证机构(Certificate Authority, CA)施加数字签名

CA就是能够认定“公钥确实属于此人”,并能够生成数字签名的个人或组织

iOS签名机制

流程

  • CertificateSigningRequest.certSigningRequest 文件 (钥匙串-证书助理-从证书颁发机构请求证书)

    Mac设备的公钥

  • .cer证书文件 (Apple Developer-Certificates)

    通过Apple私钥 (CA),对Mac设备的公钥进行签名后的证书文件

  • .mobileprovision (Provisioning Profile)

    通过Apple私钥,对[.cer,AppID,devices,entitlements]进行 签名

重签名

如果希望将破坏了签名的安装包,安装到非越狱手机上,需要对安装包进行重签名的操作

注:安装包中的可执行文件必须是经过脱壳的,重签名才会有效

.app包内部的所有动态库,(.framework、.dylib)、AppExtension (PlugIns文件夹,拓展名是appex)、WatchApp(Watch文件夹) 都需要重新签名

  • 准备一个enbedded.mobileprovision文件(必须是付费证书产生的,appid、device一定要匹配), 并放入.app包中

    • 可以通过Xcode自动生成,然后在编译后的APP包中找到
    • 可以从开发者证书网站生成下载
  • 从embedded.mobileprovision中提取出entitlements.plist权限文件

    1
    2
    security cms -D -i embedded.mobileprovision > temp.plist
    /usr/libexec/PlistBuddy -x -c 'Print :Entitlements' temp.plist > entitlements.plist
  • 查看可用证书

    1
    security find-identity -v -p codesigning
  • 对.app内部的动态库、AppExtension等进行签名

    1
    codesign -fs 证书ID xxx.dylib
  • 对.app包进行重签名

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

GUI工具

动态库注入

可以使用insert_dylib库将动态库注入到Mach-O文件中

https://github.com/Tyilo/insert_dylib

用法

1
2
3
4
5
6
7
8
insert_dylib 动态库加载路径 Mach-O文件 <新文件名>
# @executable_path 代表可执行文件所在的目录
# @loader_path 代表动态库所在的目录
# 有两个常用参数选项
--weak 即使动态库找不到也不会报错
--all-yes 后面的所有选择都为yes
# eg:
insert_dylib @executable_path/tweak_test.dylib TestAPP

insert_dylib的本质是往Mach-O文件的Load Commands中添加了一个LC_LOAD_DYLIBLC_LOAD_WEAK_DYLIB

可以通过otool查看Mach-O的动态库依赖信息

1
otool -L Mach-O文件

更改动态库加载地址

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

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

通过Theos开发的动态库插件(dylib)

默认都依赖于Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate

如果要将动态库插件打包到ipa文件中,也需要将CydiaSubstrate打包到ipa文件中,并且修改下CydiaSubstrate的加载地址

两个常用环境变量

@executable_path 代表可执行文件所在的目录
@loader_path 代表动态库所在的目录