深入了解iOS签名原理

一、加密解密

1. 密码相关

1.1 简介

根据对加密和解密使用的密钥方法,可以将密码分为2种:

  1. 对称密码:加密用的密钥和解密用的密钥是相同的。
  2. 公钥密码(非对称密码):加密用的密钥和解密用的密钥是不相同的。
1.2 对称密码(Symmetric Cryptography

常见的对称密码算法有:

  1. DES
  2. 3DES
  3. AES

解决密钥配送的方法:

  1. 提前共享密钥
  2. 密钥分配中心
  3. Diffie-Hellman密钥交换
  4. 公钥密码
1.3 公钥密码(Publick-key Cryptography

使用公钥密码解决密钥配送问题

公钥密码使用RSA算法

公钥密码中,密钥分为加密密钥、解密密钥2种,它们并不是同一个密钥。公钥密码也被称为非对称密码(Asymmetric Cryptography

加密密钥,一般是公开的,因此该密钥称为公钥(public key)。解密密钥,由消息接收者自己保管的,不能公开,因此也称为私钥(private key)。

公钥和私钥是一 一对应的,是不能单独生成的,一对公钥和密钥统称为密钥对(key pair

由公钥加密的密文,必须使用与该公钥对应的私钥才能解密。由私钥加密的密文,必须使用与该私钥对应的公钥才能解密。

由消息的接收者,生成一对公钥、私钥,将公钥发给消息的发送者,消息的发送者使用公钥加密消息

1.4 混合密码系统(Hybrid Cryptosystem

对称密码的缺点:不能很好地解决密钥配送问题

公钥密码的缺点:加密解密速度比较慢

混合密码系统,是将对称密码和公钥密码的优势相结合的方法

  • 解决了公钥密码速度慢的问题
  • 并通过公钥密码解决了对称密码的密钥配送问题

网络上的密码通信所用的SSL/TLS都运用了混合密码系统

会话密钥(session key):
为本次通信随机生成的临时密钥
作为对称密码的密钥,用于加密消息,提高速度

加密步骤(发送消息):

  1. 首先,消息发送者要拥有消息接收者的公钥(消息接受者提前生成一对公私钥)
  2. 生成随机会话密钥,作为对称密码的密钥,加密消息
  3. 用消息接收者的公钥,加密随机生成的会话密钥(使用的是非对称加密,也就是公钥加密)
  4. 将前2步生成的加密结果,一并发给消息接收者

发送出去的内容包括:

  • 用会话密钥加密的消息(加密方法:对称密码)
  • 用公钥(非对称)加密的会话密钥(加密方法:公钥密码/非对称密码)
encryption

解密步骤(收到消息):

  1. 消息接收者用自己的私钥(和消息发送者的公钥是一对)解密出会话密钥
  2. 再用第1步解密出来的会话密钥,解密消息
decryption

2. 单项散列函数

单向散列函数,可以根据根据消息内容计算出散列值,散列值的长度和消息的长度无关,无论消息是1bit、10M、100G,单向散列函数都会计算出固定长度的散列值

2.1 单项散列函数的特点:
  • 根据任意长度的消息,计算出固定长度的散列值
  • 计算速度快,能快速计算出散列值
  • 消息不同,散列值也不同,和身份证号指纹一样,是唯一的
  • 具备单向性,过程不可逆
  • 单向散列函数,又被称为消息摘要函数(message digest function),也叫哈希函数
  • 输出的散列值,也被称为消息摘要(message digest)、指纹(fingerprint
2.2 常见的几种单向散列函数

1. MD4、MD5

  • 产生128bit的散列值,MD就是Message Digest的缩写,目前已经不安全
  • Mac终端上默认可以使用md5命令

2. SHA-1

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

3. SHA-2

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

4. SHA-3

  • 全新标准
2.3 使用单项单列函数应用

1. 防止数据被篡改

通过对文件计算散列值(哈希值)的唯一性,来确定文件是否被篡改

通过对软件计算散列值(哈希值)的唯一性,来确软件是否是官方软件

2. 口令加密

将用户登录的密码计算出散列值(哈希值),保存在数据库,对比用户密码的散列值判断密码是否正确

3. 数字签名

3.1 基本概念

使用数字签名来解决消息的真实性、识别篡改、伪装、否认。

在数字签名技术中,有以下2种行为:

  • 生成签名:由消息的发送者完成,通过“签名密钥”生成
  • 验证签名:由消息的接收者完成,通过“验证密钥”验证

如何能保证这个签名是消息发送者自己签的? 可以用消息发送者的私钥进行签名。

在数字签名中,任何人都可以使用公钥验证签名,在公钥密码中,任何人都可以使用公钥进行加密

在数字签名,其实就是将公钥密码反过来使用

digitalsignature
3.2 数字签名的过程
signatureprocess

但是这样会存在一些问题:

  • 发送的数据有可能会很大
  • 会将消息发送两遍(明文消息一遍,加密消息一遍)

数字签名的改进

使用单项散列函数进行改进:

signaturehash
3.3 数字签名的作用
  • 如果有人篡改了文件内容或者签名内容,会是什么结果,结果是:签名验证失败,证明内容会篡改
  • 数字签名的作用不是为了保证机密性,仅仅是为了能够识别内容有没有被篡改

数字签名的作用:

  • 确认消息的完整性
  • 识别消息是否被篡改
  • 防止消息发送人否认
3.4 数字签名无法解决的问题

要正确使用签名,前提是:用于验证签名的公钥必须属于真正的发送者

中间人攻击:中间人通过自己生成的一对公私钥,将自己的公钥伪造成消息接受者的公钥。

attack

如果遭遇了中间人攻击,那么,公钥将是伪造的,数字签名将失效。

所以在验证签名之前,首先得先验证公钥的合法性。

所有我们要使用证书验证公钥的合法性(公钥只属于自己一人)。

4. 证书

4.1 简介

证书,联想的是驾驶证、毕业证、英语四六级证等等,都是由权威机构认证的。

密码学中的证书,全称叫公钥证书(Public-key Certificate,PKC),跟驾驶证类似:

  • 里面有姓名、邮箱等个人信息,以及此人的公钥:将这些信息生成散列值/哈希值
  • 并由认证机构(Certificate Authority,CA)施加数字签名:使用CA自己的私钥进行数字签名

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

  • 有国际性组织、政府设立的组织
  • 有通过提供认证服务来盈利的企业
  • 个人也可以成立认证机构
4.2 证书的利用

相当于将消息接受者的公钥让权威机构进行认证和签名生成证书,防止公钥被篡改。

权威机构会利用自己私钥将消息接受者的公钥等信息进行数字签名生成证书,至此,证书里面包含了消息接受者的公钥。

消息发送者拿到权威机构的证书,利用权威机构的公钥进行验证数字签名,确认消息接受者的公钥合法性,然后利用公钥加密进行消息发送

至此,通过证书,防止了公钥被篡改的风险。

usecertificate
4.3 证书的注册和下载
downloadca

二、iOS签名机制

1. 流程

iOS签名机制的作用:保证安装到用户手机上的APP都是经过Apple官方允许的

不管是真机调试,还是发布APP,开发者都需要经过一系列复杂的步骤:

  • 生成CertificateSigningRequest.certSigningRequest文件
  • 获得ios_development.cer、ios_distribution.cer证书文件
  • 注册device、添加App ID
  • 获得*.mobileprovision文件

那么,.certSigningRequest.cer.mobileprovision文件究竟里面包含了什么?有何用处?

iOS签名流程:

iossign
  1. App进行数字签名(使用Mac私钥)
  • 通过Mac的的私钥进数字签名,此时想要使用App,就必须对App进行数字签名验证,肯定是使用Mac的公钥进行验证,因为Mac的公钥和私钥是成对的。
  1. 机构(Apple自己)对Mac公钥进行数字签名,为了验证公钥合法性
  • Mac的的公钥通过Apple自己进行数字签名(使用Apple自己的私钥生成散列值/哈希值),生成证书文件.cer,证书里面包含了Mac的公钥。
  • 将证书和App的一些配置信息再次通过Apple自己进行数字签名,生成了描述文件.mobileprovision,描述文件里面包含了证书和App的配置信息。
  1. App进行验证签名(使用Mac公钥)
  • 使用Apple的公钥,对描述文件.mobileprovision进行验证签名,得到证书文件.cer
  • 使用Apple的公钥,对证书文件.cer进行验证签名,得到当初的Mac公钥
  • 使用Mac公钥,对第1步生成的App进行验证签名,进而可以正常使用App

2. 具体步骤

1.1 生成Mac设备的公私钥.certSigningRequest

钥匙串访问 -> 证书助理 -> 从证书颁发机构请求证书,生成CertificateSigningRequest.certSigningRequest文件,就是Mac设备的公钥

1.2 获得证书.cer

通过开发着后台上传CertificateSigningRequest.certSigningRequest文件,Apple会对Mac的公钥使用自己的私钥进行数字签名,最后生成证书文件.cer

1.3 生成描述文件.mobileprovision

通过开发着后台将证书文件.cerApp的信息再次使用自己的私钥进行数字签名,最后生成证书文件.mobileprovision文件。

至此,.mobileprovision文件里面包含了证书文件.cerApp的信息,证书文件.cer里面包含了Mac的公钥。

1.4 安全检测

Ad Hoc Provisoning Profile就是经过数字签名的发布描述文件,里面包含了.cer证书文件和App的信息

applevalidation
1.5 AppStore下载的验证

如果App是从AppStore下载安装的,你会发现里面是没有mobileprovision文件的,它的验证流程会简单很多,大概如下所示:

appstorevalidation
1.6 .p12文件

团队合作的时候会将.p12会进行共享

.p12文件里面包含了根证书信息和用户私钥信息

进行签名的时候就会使用.p12文件的信息进行签名

三、iOS重签名

1. 使用命令行

查看可用的证书:

security find-identity -v -p codesigning
 1) 0D5F76B2B8A2D0347126C32164CCC2FEF3445003 "iPhone Distribution: SINGAPORE TAI-E CYBER-TECH PTE. LTD. (7ffNRBZR3FF)" (CSSMERR_TP_CERT_REVOKED)

0D5F76B2B8A2D0347126C32164CCC2FEF3445003就是证书ID

  1. 准备一个embedded.mobileprovision描述文件(必须是付费证书产生的,appiddevice一定要匹配),并放入app包(.app文件显示包内容)中

  2. embedded.mobileprovision描述文件中提取entitlements.plist权限文件

    security cms -D -i embedded.mobileprovision > temp.plist
    
    /usr/libexec/PlistBuddy -x -c 'Print:Entitlements' temp.plist > entitlements.plist
    

    将生成的entitlements.plist权限文件和.app文件放在文件夹Payload中。

  1. .app包进行重签名:

    codesign -fs 证书ID --entitlements entitlements.plist xxx.app
    

    .app内部的动态库、AppExtension等进行签名:

    codesign -fs 证书ID xxx.dylib
    
  2. entitlements.plist删除,对PayLoad文件进行压缩为.zip,再将.zip修改为.ipa

2. 使用GUI工具

2.1 iOS App Signer

可以对.app重新签名打包成ipa。需要在.app包中提供对应的embedded.mobileprovision文件

2.2 iReSign

可以对ipa进行重签名,需要提供entitlements.plistembedded.mobileprovision文件路径

你可能感兴趣的:(深入了解iOS签名原理)