从0开始深入理解iOS的签名机制
前言
假设Alice
、Bob
两个人现在要互相发信息,但有一个不怀好意的Eve
想要窃听他们之间的消息
如何防止被不怀好意的人窃听?
通过一个加密手段,消息的发送者通过一个密钥将消息的内容加密后,然后再发送给接收方Bob,Bob收到加密的消息内容之后,然后再利用密钥进行解密即可
由于监听者Eve没有密钥,此时它只能监听到加密的内容,无法查看真正的消息内容
根据密钥的使用方法,可以将密码分为两类:
- 对称密码
- 公钥密码(非对称密码)
对称密码
在对称密码
中,加密、解密用的都是同一个密钥
常见的对称加密算法有:
- DES(Data Encryption Standard)
- 一种将64bit明文加密成64bit密文的对称密码算法,密钥长度是56bit
- 目前可以比较容易被破解出来,所以不建议使用
- 3DES
- 使用
DES
用3个不同的密钥重复3次计算所得到的的一种密码算法 - 如果3个密钥都相同,则结果与普通的DES是等价的
- 使用
- AES(Advanced Encryption Standard)
- 取代
DES
称为新标准的一种对称密码算法 AES
的密钥有128、192、256bit三种- 已经取代
DES
、3DES
称为主流的对称密码算法
- 取代
密钥配送问题
由于对称加密
的密钥都是同一个,所以存在一个密钥配送的问题,如果密钥一旦被窃听者截取,那么加密就如同虚设
所以就存在了如何安全的进行密钥交换,目前主要有以下方式:
- 事先共享密钥
- 密钥分配中心
- Diffie-Hellman密钥交换
- 公钥密码(非对称加密)
公钥密码
公钥密码
(Public-key Cryptography),也叫做非对称加密
,密钥分为加密密钥
和解密密钥
两个,他们并不是同一个密钥也不相等
公钥密码
加密有以下特点
加密密钥
一般是公开的,因此该密钥被称为公钥
(public key)解密密钥
由消息接收者自己保管,不公开,因此称为私钥
(private key)公钥
和私钥
是一一对应的,不能单独生成- 由
公钥
加密的密文,必须使用私钥
才能解密 - 由
私钥
加密的密文,必须使用公钥
才能解密
利用公钥密码
就可以解决密钥配送
的问题
目前使用最广泛的
公钥密码
算法是RSA
RSA的名字是由它的3位创造者的名字首字母组合而来的(RonR
ivest、AdiS
hamir、LeonardA
dleman)
混合密码系统
对称密码
的缺点是不能很好的解决密钥配送问题
而公钥密码
的缺点是加解密的速度又有点慢
所以也就诞生了混合密码系统
(Hybrid Cryptosystem),它是将对称密码和公钥密码的优势相结合的方法;解决了公钥密码加解密速度慢的问题,同时又解决了对称密码的密钥配送问题
网络上的密码通讯所使用的的SSL/TLS都运用了混合密码系统
混合密码-加密
会话密钥
(session key)作为本次通信随机生成的临时密钥,同时又作为对称密码的密钥,用于加密消息,以此来提高速度
加密步骤
- 首先,消息发送者要拥有消息接收者的公钥
- 生成会话密钥,作为对称密码的密钥,用于加密消息
- 用消息接收者的公钥,加密会话秘钥
- 将前两步生成的加密结果,一并发送给消息接收者
发送出去的内容包括
- 用会话密钥加密的消息(加密方法:对称密码)
- 用公钥加密的会话密钥(加密方法:公钥密码)
混合密码-解密
解密步骤
- 消息接收者用自己的私钥解密出
会话秘钥
- 再用
第一步
解密出来的会话密钥
,解密消息
混合密码-完整流程
Alice
发送消息给 Bob
发送过程,加密过程
- Bob先生成一队公钥、密钥
- Bog把公钥功效给Alice
- Alice随机生成一个会话密钥(临时密钥)
- Alice用会话密钥加密需要发送的消息(使用对称加密)
- Alice用Bob的公钥加密会话密钥(使用非对称加密)
- Alice把第4、5步的结果,一同发送给Bob
接收过程,解密过程
- Bob利用自己的私钥解密会话密钥(使用非对称加密)
- Bob利用会话密钥解密发送过来的信息(使用对称加密)
单向散列函数
单向散列函数
(One-way hash function)是指可以根据消息内容计算出散列值
散列值
的长度和消息的大小无关,无论消息是1bit,1M等等,单向散列函数都会计算出固定长度的散列值
有以下特点:
- 计算速度快
- 消息不同,散列值也不同
- 具备单向性(无法根据散列值反向得到消息内容)
常见的几种单向散列函数
- MD5
- 产生128bit的散列值
- Mac终端上默认可以使用md5命令
- SHA-1
- 产生160bit的散列值,不太安全
- SHA-2
- SHA-256、SHA-384、SHA-512,散列值长度分别是256bit、384bit、512bit
- SHA3
- 全新标准
单向散列的应用
针对单向散列的特点,通常在实际开发当中用于做一些数据防篡改、比对的校验
比如登录系统当中的密码校验等等
数字签名
graph LR
发送者 ==消息内容===> 接收者
消息的发送者在向接收者发送一段消息时,接收者如何确保消息的真实性(有没有被其他人篡改)?
一个比较好的解决方案:数字签名
在数字签名技术中,有以下两种行为:
- 生成签名(由消息的发送者完成,通过签名密钥完成)
- 验证签名(由消息接收者完成,通过验证密钥完成)
数字签名
其实就是将公钥密码
反过来使用(使用私钥加密,使用公钥验证)
一个完整的使用数字签名的示例:
数字签名不是为了保证机密性的,它主要的作用其实是防止内容被篡改
但数字签名
其实也存在一个巨大的问题,那就是中间人攻击
中间人
自己生成了一份私钥
和公钥
,通过窃取刚开始消息发送者和消息接收者之间
传输的公钥
,自己保存了这个正确的公钥,然后将自己的公钥给到了发送者
而发送者后面发送的消息内容,都是经过中间人
的公钥加密的,中间人就能够解出来,然后篡改其内容,再通过正确的公钥加密,最终发送给接收者,这样就完成了消息的篡改.
所以验证公钥的合法性就是最重要的了,这个时候就要用到证书
证书
证书
(Certificate),都是由权威机构认证的
密码学中的证书,全称叫做公钥证书
(Public-key Certificate,PKC), 里面有姓名、邮箱等个人信息,以及此人的公钥
, 并由认证机构
(Certificate Authority,简称CA)施加数字签名
CA
就是能够认定“公钥确实属于此人”并能够生成数字签名的个人或者组织
一个简单的证书注册
流程
证书的使用流程
由于消息接收者
在生成密钥对
的时候,并不是直接传输公钥
给消息发送者,而是将公钥
提交到了认证机构Trent(虚拟的)
, 所以在这一步中间者也就无从窃取公钥了
而消息发送者
是直接在认证机构获取的证书(包含公钥、数字签名), 为了验证这个证书是否合法,它还可以使用机构提供的公钥
来验证数字签名是否准确,一旦验证通过后,就可以放心的使用这个证书进行加密发送消息了。
iOS签名机制
iOS签名机制的作用其实就是为了保证安装到用户手机上的APP都是经过Apple官方允许
的, 签名的机制分为两种App Store的签名机制
和XCode开发的签名机制
App Store下载的签名机制
当 App 提交审核通过后,Apple 会对 App 进行重签名。因此,从 App Store 下载的 App ,统一都是苹果的官方签名。验证机制也较为简单。
它的主要流程:
- Apple 官方保存着私钥,在App提交审核通过后,会通过私钥对其进行重签名;
- iOS 系统内置公钥,用户从 App Store 下载 App ,iOS 系统通过公钥对其进行签名验证;
- 验证通过,则说明该 App 是经过苹果认证的,未经篡改的,允许运行,否则,拒绝运行。
XCode开发的签名机制
在XCode
中开发时,用的是开发证书。需要针对不同的开发者账号进行验证,签名机制较为复杂。
开发者身份验证
在 Apple Developer 生成证书时,为了验证开发者身份,需要在本地 keychain 中生成公私钥,公钥保存在 CertificateSigningRequest 文件中,上传到 Apple Developer ,私钥如果需要给其他开发者用,可以导出为 .p12 文件。
生成证书
Apple Developer 后台接收到开发者公钥后,利用 Apple 的私钥对其进行签名,生成证书cer。
验证设备
除了验证开发者身份,还需要验证 AppID 和设备的 UUID , 权限控制 Entitlements 等,把这些信息和上面生成的证书一起,再用 Apple 的私钥进行一次签名,生成最终的 mobileprovision 文件。
签名APP
在XCode编译后,生成 App 文件时,会对其通过开发者私钥进行签名,将 mobileprovision 文件命名为 embedded.mobileprovision 并将其打包到 App 文件中。
在通过开发者私钥签名 App 时,对于可执行文件( Mach-O ),会将签名直接写入到该文件中,而对于其他的资源文件,会统一写到 _CodeSignature 文件下的 CodeResources 文件中。
验证签名
在安装 App 文件时,首先通过 iOS 系统内置的 Apple 公钥对上面的签名进行验证,包含开发者共私钥匹配,设备 ID,App ID,权限控制 Entitlements ,证书有效期验证等。
本文首次发布于 孙忠良 Blog, 作者 [@sunzhongliang] , 转载请保留原文链接.