iOS逆向学习(加密、签名)

542 阅读15分钟

学前须知

虚拟人物设计

为了方便我们学习iOS的签名机制,本文设置了4个虚拟人物,分别是

  • Alice、Bob:相互通信
  • EVe:窃听者
  • Mallory:主动攻击者

消息通信与窃听

  • 未使用加密时,通信双方以明文通信

  • 但是这种通信方式很容易被他人窃听,从而被盗取机密信息

  • 那么如何防止信息被监听呢?就需要对通信信息进行加密操作。

    首先将明文加密成密文发送给接收方

接收方拿到密文后进行解密得到明文数据

通过加密之后,就算有他人窃听通信数据,也只能得到被加密后的密文数据

加密解密

如何进行加密解密

  • 消息发送者使用密钥进行加密
  • 消息接收者使用密钥进行解密

密码的类型

根据密钥的使用方式,我们可以将密码分为两种:对称密码和公钥密码。

对称密码

对称密码就是加密和解密使用相同密钥

常用的对称密码算法有三种

DES(Data Encryption Standard)

3DES

AES(Advanced Encryption Standard)

AES是用来取代DES称为新标准的一种对称密码算法,AES的密钥长度有128、192、256bit三种。

密钥配送问题

什么是密钥配送问题?

使用对称密码时,一定会遇到密钥配送问题,具体如下图

假设Alice将使用对称密码加密后的消息发送给Bob,Bob想要查看明文信息,就需要拿到Alice加密的密钥,所以Alice同时要将密钥发送给Bob,在发送密钥的过程中,可能会被Eve窃听,Eve拿到窃取的密钥和密文,同样可以解析得到明文消息。

怎样解决密钥配送问题?
  • 事先共享密钥。也就是Alice和Bob事先私下共享密钥,不能通过网络传输。不过这种方式非常麻烦,不建议使用。
  • 密钥分配中心
  • Diffie-Hellman密钥交换
  • 公钥密码。公钥密码是现在普遍使用的一种方式,也是我们主要学习的一种方式。

公钥密码

公钥密码中,密钥分为加密密钥和解密密钥两种,它们不是同一个密钥,所以公钥密码又被称为非对称密码(Asymmetric Cryptography)

在公钥密码中:

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

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

上面说到,密钥配送问题可以通过公钥密码来解决,具体解决流程如下:

  • 首先,消息接收者生成一对公钥和私钥。
  • 将公钥发给消息发送者。
  • 消息发送者用公钥对消息进行加密。
  • 消息发送者将加密后的密文发送给消息接收者。
  • 消息接收者用私钥对密文进行解密,得到明文数据。

RSA

RSA是目前使用最广泛的公钥密码算法。它的名字是由3位开发者Ron Rivest、Adi Shamir、Leonard Adleman的姓氏首字母组成。

混合密码系统

对称密码和非对称密码的对比

  • 对称密码不能很好的解决密钥配送问题
  • 公钥密码加密和解密速度比较慢,因为消息本身多大,加密后的密文就有多大,所以对于大批量的数据,加密解密速度过慢。
  • 为了解决密钥配送问题,同时提升加密解密的速度。于是采取了将对称密码和公钥密码相结合的方式,取长补短。现在网络上密码通信所用到的SSL/TLS都是运用了混合密码系统。

混合密码系统-加密

会话密钥(session key)

  • 会话密钥是专门为本次通信随机生成的临时的密钥,使用伪随机数生成器来生成
  • 会话密钥作为对称密码的密钥,用来对消息进行加密,从而提高速度

加密步骤-发送消息

  • 第一步,消息发送者需要拿到消息接收者的公钥
  • 第二步,生成会话密钥,作为对称密码的密钥,将消息加密成密文
  • 第三步,使用消息接收者的公钥,来加密会话密钥
  • 第四步,将第二步和第三步生成的加密结果一起发送给消息接收者

发送的内容包括

  • 用会话密钥加密的消息(使用对称密码加密)
  • 用公钥加密的会话密钥(使用公钥密码加密)

混合密码系统-解密

收到==消息发送者==发过来的消息之后,需要进行解密操作,具体步骤如下:

  • 第一步,消息接收者用自己的私钥解密出会话密钥
  • 第二步,用第一步解密得到的会话密钥解密消息,得到明文数据

混合密码系统-加密解密完整步骤总结

使用Alice作为==消息发送者==,Bob作为消息接收者

发送消息(加密)

1,Bob首先生成一对公钥、私钥 2,Bob将公钥共享给Alice 3,Alice随机生成一个会话密钥(临时密钥) 4,Alice用会话密钥加密需要发送的消息(对称密码加密) 5,Alice用Bob的公钥加密会话密钥(公钥密码加密、也称为非对称密码加密) 6,Alice将4、5步加密得到的结果一起发送给Bob

接收消息(解密)

1,Bob利用自己的私钥解密会话密钥(公钥密码解密、也称为非对称密码解密) 2,Bob使用会话密钥解密发送过来的消息(对称密码解密)

单向散列函数 (哈希函数)

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

单向散列函数的特点

  • 根据任意长度的消息,计算出固定长度的散列值。
  • 计算速度快,能够快速计算出散列值
  • 消息不同,哪怕就相差1bit数据,散列值也不同

  • 具备单向性,不可逆

常用的单向散列函数

单向散列函数又称为消息摘要函数、哈希函数。输出的散列值也被称为消息摘要、指纹。常见的几种单向散列函数如下

MD4、MD5

产生128bit的散列值,MD就是Message Digest的缩写,目前已经不安全

SHA-1

产生160bit的散列值,目前也不安全

SHA-2

SHA-256、SHA-384、SHA-512,散列值的长度分别为256bit、384bit、512bit。散列值长度越大,安全性就越高

SHA-3

SHA3(Secure Hash Algorithm-3)是一种作为新标准发布的单向散列函数算法,用来替代在理论上已被找出攻击方法的SHA-1算法。全世界企业和密码学家提交了很多SHA-3的候选方案,经过长达5年的选拔,最终于2012年正式确定将Keccak算法作为SHA-3标准。

单向散列函数的应用

防止数据被篡改

  • 防止文件被篡改,具体的做法是将文件通过单向散列函数得到散列值。将散列值存放到安全的地方。如果一段时间后,文件被篡改,那么拿到最新的文件,通过单向散列函数,得到最新的散列值,同之前的散列值进行对比,就可以确定文件是否被篡改。

  • 软件被篡改。一般为了分散通信负荷,一些软件公司会将自己的软件放在镜像站点上供用户下载。那么用户如何判断从镜像站点下载的软件是否被恶意篡改呢?一般软件公司会将软件通过散列函数得到的散列值放在官网上,供用户来对比,只要用户下载的软件得到的散列值和官网一致,那么就表明用户下载的软件没有被恶意篡改过。例如软件VNC,可点击VNC官网查看

口令加密(数据库存的不是密码而是散列值)

在App登录时,一般都需要进行账号和密码的校验,但是在数据库中,保存的密码一般都是进行SHA-2散列函数之后的散列值而不是明文密码,所以在登录时需要对用户输入的密码进行散列算法,得到散列值,再同数据库保存的散列值进行比较,从而判断密码是否正确。 并且,由于散列函数的不可逆,就算他人通过不正当手段获取到数据库中存放的密码的散列值,也无法获取到用户的真实密码。这样就大大增加了用户数据的安全性

数字签名

其实,不管是使用之前的对称加密、非对称加密还是混合密码系统,都无法验证消息的真实性。也就是说消息的接收者无法判断这条消息是否是消息发送者所发出的。也有可能是他人伪装成消息发送者发出的消息。那么怎么来验证消息的真实性呢?通过数字签名的方式来验证。

数字签名的两种行为

  • 生成签名。主要由消息发送者完成,通过“签名密钥”生成
  • 验证签名。由消息接收者完成,通过“验证密钥”验证 那么,如何保证这个签名是消息发送者自己签的呢?答案就是使用消息发送者自己的私钥进行签名。上文中,我们知道公钥密钥是公开的,所有人都能拿到的,所以在公钥密码中,任何人都能使用公钥进行加密。

而在数字签名中,任何人都可以使用公钥来验证签名。

数字签名和公钥密码的对比

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

数字签名的过程

普通数字签名过程

  • 首先,消息发送者生成一对公钥、私钥。
  • 消息发送者将公钥发送给消息接收者。
  • 消息发送者用自己的私钥对消息进行加密,得到签名信息。
  • 消息发送者将消息和签名一起发送给消息接收者。
  • 消息接收者使用消息发送者的公钥对签名信息进行解密,得到签名中的消息
  • 消息接收者将解密得到的消息和直接得到的消息进行对比,如果两者一致,则说明签名验证成功。

但是这样的签名过程速度很慢,因为签名信息是通过加密原有的消息获得,如果消息大小是1M,加密后的签名大小也是1M,最后发送给消息接收者的消息就是2M

改进数字签名的过程

在之前数字签名的过程上使用单向散列函数进行改进。

  • 首先消息发送者使用单向散列函数计算消息的散列值
  • 消息发送者使用自己的私钥对第一步获取到的散列值进行加密,生成签名信息
  • 消息发送者将签名信息和消息一起发送给消息接收者
  • 消息接收者使用消息发送者的公钥对签名信息进行解密,得到解密后的散列值
  • 消息接收者对消息进行单向散列计算,得到散列值
  • 消息接收者将签名中解密得到的散列值和直接进行散列函数得到的散列值进行对比,如果一致则签名验证成功。

完整的签名过程

数字签名的作用

综合以上几点,可以总结出数字签名的作用:

  • 确认消息是否完整
  • 识别消息内容是否被篡改
  • 防止消息发送者否认发送此消息

数字签名的问题

  • 首先思考一下,如果有人篡改了文件的内容或者是签名的内容,会导致什么结果?结果就是签名验证失败,证明了文件内容被篡改。
  • 再者,数字签名的过程中,将消息的明文直接发送给了消息接收者,无法保证消息的安全性?数字签名的作用并不是为了保证数据的机密性,仅仅是为了能够识别消息内容有没有被篡改。

要想正确的使用数字签名,就必须验证签名的公钥必须属于真正的发送者。因为在消息发送者和消息接收者之间可能会遭遇中间人攻击,具体攻击步骤如下:

  • 消息接收者将自己的公钥发送给消息发送者。
  • 中间人窃听到了通信的内容,获取到了消息接收者发出去的公钥。
  • 中间人拦截消息接收者的公钥,将自己的公钥发送给了消息发送者
  • 消息发送者误以为是消息接收者发送过来的公钥,使用接收到的公钥对消息进行加密,然后将密文发送给消息接收者。
  • 中间人拦截到密文,使用自己的私钥进行解密,获取到明文消息。然后使用之前拦截到的消息接收者的公钥对消息进行加密,将伪造的密文发送给消息接收者。
  • 消息接收者接收到密文,用自己的私钥进行解密,最终得到明文消息。

以上的消息传递过程中,消息发送者和消息接收者无法察觉到中间人的存在,但是消息已经被泄漏了。

上面的通信过程遭遇到了中间人的攻击,会导致

  • 公钥是中间人伪造的
  • 数字签名失效

因此,在验证签名之前,首先得验证公钥的合法性。如何验证公钥的合法性呢?就需要通过证书。

证书

看到证书,我们会联想到驾驶证、毕业证等等,这些证书都是由权威机构认证的。在密码学中的证书,全称叫做公钥证书(Public-key Certificate,PKC)。和驾驶证、学生证类似。

证书的使用

证书的使用有以下几个步骤:

1,消息接收者生成自己的密钥对,消息接收者在认证机构注册自己的公钥 2,认证机构用自己的私钥对消息接收者的公钥施加数字签名,并且生成证书 3,消息发送者从认证机构那得到带有认证机构数字签名的消息接收者的公钥(证书) 4,消息发送者使用认证机构的公钥验证数字签名,确认消息接收者公钥的合法性。 5,消息发送者使用消息接收者公钥加密消息,并且发送给消息接收者。 6,消息接收者使用自己的私钥解密密文得到最终的消息

增加认证机构认证流程之后,消息发送者和消息接收者之间,就不存在公钥的传递过程,消息发送者从认证机构获取消息接收者的公钥,这样就杜绝了中间人攻击导致公钥伪造的问题


证书的注册和下载流程如下

  • 消息接收者到认证机构注册公钥
  • 认证机构对消息接收者的公钥进行数字签名,生成证书保存到仓库中
  • 消息发送者从认证机构的仓库中下载证书
  • 消息发送者使用认证机构的公钥对证书进行验证,得到消息接收者的公钥

小结

对称加密和公钥加密(非对称加密)

对称加密,相同的密码加解密(DES,3DES) 公钥加密,公钥加密私钥解密(RSA)

混合密码系统

使用对称密码加密信息,使用公钥密码加密会话密钥。 现在网络上密码通信所用到的SSL/TLS都是运用了混合密码系统

单项散列函数(哈希函数)

1,根据任意长度的消息,计算出固定长度的散列值。消息不同,哪怕就相差1bit数据,散列值也不同。

2,常用的单向散列函数。MD4,MD5产生128bit的散列值,MD就是Message Digest(消息摘要)的缩写,目前已经不安全。

3,SHA3(Secure Hash Algorithm-3)是一种作为新标准发布的单向散列函数算法

数字签名

数字签名为了验证此消息是从消息发送者发出的。(因为要自己发送密钥,会被中间人攻击)

证书

增加认证机构认证流程之后,消息发送者和消息接收者之间,就不存在公钥的传递过程,消息发送者从认证机构获取消息接收者的公钥,这样就杜绝了中间人攻击导致公钥伪造的问题。