没怎么涉及算法细节,主要是掌握加密的各种基础概念。
题外话:其实每在学习新事物的时候都非常享受“理论基础”这个阶段,给人的感觉就像是在查字典,一个在不断给生词祛魅的过程,可以说是学习过程中精神享受最强烈的一步罢。
对称加密
DES: Data Encryption Standard, 数据加密标准
AES: Advanced Encryption Standard, 高级加密标准
最传统也是应用最广泛的加密方案,由五个基本成分组成:
- 明文:算法的输入,是原始的可理解的消息或数据
- 加密算法:用于对明文进行各种变换
- 秘密密钥:算法的输入,加密算法对明文数据采用的变换方法依赖于密钥
- 如果把加密算法看成一个函数,那秘密密钥就是函数的参数
- 密文:算法的输出,看起来是完全随机且杂乱的数据
- 解密算法:加密算法的逆运算,输入密文和秘密密钥可以恢复明文
评估一个对称加密方案是否安全(或者说评估它的强度)需要从算法本身和密钥使用两个方向考虑:
- 加密算法必须足够 强
- “强”的含义是,即使敌手拥有一定数量的密文和对应的明文,也不能破译出密文或者发现密钥
- 发送者和接收者必须保证秘密密钥的安全
而攻击一个对称加密体制也有两种基本办法。
第一种是 密码分析学 ,从密码分析学出发的攻击依赖于算法的性质和得到的一些样本 —— 这个样本可以是推导得到的明文的一般特征,也可以是一些明文 - 密文对的样本。可见如果加密方案在算法方面不够强,使得密钥被成功推导出,后果就将是灾难性的,这意味着所有过去和未来使用该密钥加密的信息都变得不安全了。
第二种是穷举攻击,或者说 蛮力攻击 。它的思路很简单:对一条密文尝试使用所有可能的密钥,直到将其转化为可读的有意义的明文。但鉴别明文是否可读这一步本身在缺少关于具体明文的知识时实现起来并不太容易,如果文本消息是其他语言的,或者在加密传输之前压缩过等,自动识别将会很难实现。
目前来看,保护密钥似乎比保护加密算法本身更加重要。
看知乎上相关从业人员的观点是:
- “算法是保密不住的。”
- “信息的保密性寓于密钥的保密而不是算法的保密,这是全球密码学界公认的原则。”
- “根本用不着通过反编译去分析其中的加密原理,对于有经验的密码破译或密码分析人员,只须通过几组明密文对攻击,就可以分析出其中的加解密算法。”
需要强调的是,任何加密方法的安全性(不局限于对称加密)都依赖于密钥的长度和破译密码所需要的计算量。
对称分组加密算法
即分组密码,是使用最广泛的对称加密算法,本质是将定长的明文转换成与明文等长的密文。因此处理较长的明文时,需要将明文划分为一系列定长的块,这就是“分组”的含义。DES、AES 和三重 DES 都使用了分组密码。
数据加密标准 DES
使用最广泛的加密体制,其使用的加密算法本身被称为 DEA ,即 Data Encryption Algorithm 。
DES 采用 64 位长度的明文分组和 56 位长度的密钥,产生 64 位长度的密文分组。根据前述的两个方向评估 DES 的加密强度的话:从算法本身而言,至今还没有关于 DES 算法本身致命弱点的相关报道(在它已经是现在研究最深入的加密标准这一前提下),并且 DES 加密算法比任何其他加密算法被分析破解所需要的时间都要长得多,因此算法本身的强度还是非常可观的;而从密钥长度角度分析,56 位的密钥只有 种可能,考虑到现在的商用处理器速度和并行运算的效率,这个长度严重不足,很容易被蛮力攻击法破解。可行的解决方法是提高密钥的长度,128 位或者更多位密钥可以保证算法不会被简单蛮力破解。
三重 DES 算法(3DES)
这是一个用于替代 DES 的加强版加密标准使用方案,延长了 DES 算法的寿命。顾名思义,它重复基本的 DES 算法三次,采用两个或者三个不同的密钥,密钥长度位 112 位或者 168 位,明文分组长度依旧为 64 位。
- 优点
- 密钥长度足够长,能够克服 DES 面临的蛮力攻击问题
- 底层加密算法与 DES 的加密算法相同,对密码分析攻击有很强的免疫力
- 缺点
- 用软件实现算法的速度比较慢(一开始是为了 1970s 的硬件实现而设计的)
- 就效率和安全性而言,分组长度不够长
高级加密标准(AES)
它诞生的动机是 3DES 的替代品 —— 要求同时具有 3DES 的安全强度和高于它的计算效率。它采用分组长度为 128 位的对称分组密码,并能支持长度为 128 、192 和 256 位的密钥。
对称加密面临的实际安全问题
我们看到,使用对称加密时,我们需要将明文消息源分成固定分组长度的分组序列。最简单的多分组加密方式被称为电码本模式(ECB),ECB 的工作过程就是将长度为 的明文分成 个 位的分组,每个分组用相同的算法和密钥加密得到一段密文,最后拼成一个密文序列。可见:如果消息很长且结构化特征很明显(比如总是以某些固定的字符开头),密码分析者就可以获取大量的明文 - 密文对,展开密码分析攻击。
为了增强用于加密大数据序列的对称分组密码的安全性,也涌现出了很多可选择的其他技术,它们被称为 操作模式 (mode of operation)。
流密码
一个与分组密码(block cipher)相对的概念。分组密码的输入是一个元素分组,输出是与输入相对的一个分组,处理是相对离散的;而流密码则持续处理输入元素,对每一个输入元素都产生一个元素的输出。一个典型的流密码每次加密一个字节的明文,流密码也可以被设计为每次操作一位或者大于一个字节的单元。如果需要对数据流进行加解密(比如在一个数据通信信道上),流密码加密比分组密码要更合适一些。
流密码加密的经典流程是:将密钥输入到一个伪随机位发生器中,让它输出一串随机的数,这个输出被称为密钥流 keystream ;然后使用密钥流与明文流进行逐位的异或运算。在这里,伪随机数发生器的地位跟分组密码加密中的加密算法差不多,通过设计合适的发生器,流密码可以提供和相应密钥长度的分组密码相当的安全性。
消息认证和散列函数
对数据加密的要求是防止攻击 —— 攻击分为主动攻击和被动攻击。上述的加密算法防止的是诸如窃听这样的被动攻击,但无法防止诸如数据伪造和篡改这样的主动攻击,应对这类攻击的方法中最著名的是 消息认证 或数据认证。
认证的功能相当于水印,用于允许通信者验证所接收或存储的数据是否可信(可信的含义包括数据是否真实以及数据的来源是否合法),一般来说还要求认证可以验证消息的时效性,即消息没有被人为地延迟或者重放,对于对称加密而言,可能还需要附加每个分组的序号 —— 毕竟如果攻击者重组了密文分组,也会改变整个数据序列的意义。所以总结而言,认证应当可以验证消息数据的 完整性 (这个数据完整性的描述与数据库中所学的是类似的)。
一般的消息认证方法是无机密性的,不依赖于消息加密,其基本思路是生成认证标签,附加在消息明文上用于传输。下面讨论集中无机密性的消息认证技术。
消息认证码(MAC)
一种认证技术是:数据发送方利用一个只有收发双方知道的秘密密钥 ,计算生成一个固定长度的短数据块 —— 即消息认证码,是一个关于消息和秘密密钥的复杂函数 ,不需要是可逆的 —— 附加在消息之后,接收方对收到并解密得到的消息利用相同的秘密密钥和计算方法生成一个新的消息认证码,并将其与收到的认证码进行比较,如果接收到的认证码和计算得到的认证码相同,接收方就可以确认以下的认证信息:
- 消息没有被修改
- 消息来自真实的发送方
- 假设秘密密钥只有收发双方知晓
- 如果消息中含有序号,则认为消息顺序是正确的
- 例如网络报文中使用的序号
DES 可以用来生成认证码,一般的操作是将消息的加密密文的最后几位作为认证码(通常是 16 位或者 32 位的)。可以看到,消息认证码的长度是比较短的,所以理论上大量的消息一定会产生相同的 MAC ,但实际中很难找到具有相同 MAC 的消息对,这一特性被称为 抗碰撞性 。
单向散列函数
是 MAC 的一种变形。它接受可变长度的消息 M 作为输入,产生固定长度的消息摘要 作为输出。在真正用 Hash 函数处理消息之前,一般会将输入消息先填充到某个固定长度的整数倍(比如 1024 位),填充进去的内容包括 原始消息的长度 这种特征字段,这既是算法的需要,也是一种安全措施,它增加了攻击者利用 Hash 值改变消息(即产生具有相同 Hash 函数值的另一个消息混淆视听)的难度。
得到可信的消息摘要之后,需要再对其进行加密,然后才和消息一起进行传输。加密消息摘要以及利用 Hash 值进行消息认证的方法有三种:
- 利用 对称加密
- 利用 公钥加密
- 可以提供数字签名和消息认证,不要求密钥分发到通信双方
- 利用 秘密值
- 利用 Hash 函数但没使用加密,通信的安全性由一个只有收发双方知道的秘密密钥 保证。由于秘密密钥本身没有被发送,因此只要它是安全的,攻击者就不可能生成伪消息
为什么需要讨论 利用秘密值 这类完全不使用加密函数的认证方法呢?主要原因是加密操作本身的硬软件开销不可忽视(特别是针对小数据分组而言,一般的加密硬件都是针对大量数据做优化的),加密算法本身也可能受到专利保护。
安全散列函数
感觉像是对散列函数施以安全性约束后得到的一个概念。从安全的角度出发,对一个能用于消息认证的散列函数 的要求有以下几点:
- 可用于任意大小的数据块
- ?感觉反正要填充,还是说填充操作本身是 的一部分呢
- 产生固定长度的输出
- 对任意给定的 ,计算 比较容易,用硬件和软件均可实现
- 对任意给定的散列码 ,找到满足 的 在计算上不可行
- 这是“单向散列函数”中 单向 的含义,也被称为是 抗原象 的(preimage resistant)。
- 对于 ,称 为 的原象
- 具体而言,单向性被称为 第一抗原象
- 这一特性对于使用秘密值的认证方法来说非常重要,一旦散列函数不单向,秘密值就可以容易地被破解
- 这是“单向散列函数”中 单向 的含义,也被称为是 抗原象 的(preimage resistant)。
- 找到任何满足 的偶对 在计算上是不可行的
- 即前面提到过的 抗碰撞 特性(collision resistant)
- 抗弱碰撞性:也被称为 第二抗原象 ,指对于给定的消息 ,想要发现另一个消息 使得 在计算上是不可行的
- 抗强碰撞性:对于任意一对不同消息 ,使得 在计算上是不可行的,即保证不同消息产生的散列码一定不同
- 如果满足前面的性质但不满足这条, 被称为弱散列函数,否则称为强散列函数。强散列函数可以阻止一个实体伪造另一个实体已经签名的消息(比如根据一个已经签名过的消息,伪造一条散列值相同、但消息含义完全不同的“已签名”假消息 —— 毕竟是否签名这件事本身就是通过比较消息摘要得到验证的)
- 即前面提到过的 抗碰撞 特性(collision resistant)
评估散列函数安全性的方法跟评估对称加密一样,也是从密码分析攻击和蛮力攻击两个角度出发。散列函数抗蛮力攻击的能力仅仅依赖于算法所产生的散列码的长度。对于长度为 的散列码,所需的代价为:
- 第一抗原象:
- 第二抗原象:
- 抗强碰撞:
近年来使用最广泛的散列算法是 安全散列算法 SHA(Secure Hash Algorithm,就是我们经常听到的 SHA-256 等标准中的 SHA)。它包括以下的版本:
- SHA-1:产生 160 位的散列值
- SHA-2
- 包括 SHA-256、SHA-384、SHA-512
- 与 SHA-1 具有相同的基本结构、相同类型的模运算和逻辑二元运算
- SHA-3
- 与 SHA-1、SHA-2 的结构截然不同
除了用于消息认证,散列函数还有很多其他的应用,包括口令(做软工的时候应该深有体会,不管是操作系统中还是浏览器中,存储的必然是口令的散列值而不能是口令明文本身)、文件入侵检测等。
公钥加密
一般应用于消息认证和密钥分发中。公钥密码体制基于数学函数而非基于位模式的简单操作,它是 非对称 的,使用两个单独的密钥。由于运算过程比较复杂,成本较大,我们一般不使用公钥加密直接对明文消息本身进行加解密操作,而是将它用于认证或者密钥分发等,后面会介绍它的应用。
公钥密码体制的组成部分是:
- 明文:算法的输入
- 加密算法
- 公钥和私钥:这是选出的一对密钥,一个用于加密,一个用于解密
- 加密算法执行的变换依赖于公钥和私钥
- 公钥对其他使用者来说是公共的,私钥却只有它的拥有者知道
- 密文:算法的输出
- 解密算法:接收密文和相应的密钥,产生原始明文
在公钥密码体制下,存在着 公钥加密 和 私钥加密 两种运算模式。
公钥加密 的步骤是:
- 每个用户生成一对密钥。其中一个放在公共寄存器或者其他可访问的公共文件中,称为公钥;另一个密钥自己持有,不进行分发,称为私钥
- 每个用户可以拥有若干个其他用户的公钥,称为 公钥环 ,想象成一个钥匙扣上有很多其他人的钥匙
- 如果 Bob 想要给 Alice 发送消息,就从公钥环中找到 Alice 的公钥,用这个公钥加密信息。Alice 收到消息后,用只有自己知道的私钥对消息解密
- 只要系统控制了私钥,通信就是安全的。在任何时刻,系统可以改变其私钥,并公布相对应的公钥以代替原来的公钥
私钥加密 的步骤是,如果 Bob 想要给 Alice 发送消息,就先使用自己的私钥加密数据,Alice 收到消息后从公钥环里找到 Bob 的公钥对数据进行解密。
这两种方案是有区别的。公钥加密方案提供了 机密性 —— 只有期望的接收者才能解密出数据,因为只有期望的接收者拥有所要求的私钥;而私钥加密方案提供的是 认证 和数据完整性 —— 如果一个用户可以成功使用 Bob 的公钥还原密文,说明原始明文的加密方是 Bob 本人,因为只有 Bob 拥有所要求的私钥。
有一个非常有用的对密码算法的约束条件是 可交换性 ,也即令加解密函数的顺序可交换,满足:
如果满足可交换性,就可以基于同一套密码系统实现两种运算模式,或者说,此时同一个基于两个相关密钥的密码算法能够同时支持两种运算模式。不是所有公钥密码应用都需要满足这个条件。
公钥证书
顾名思义,公钥的含义就是它是公开的,这一点在公钥分发这一步存在很大的缺陷 —— 这意味着任何人都可以伪造一个公共通告,假冒某个用户向其他参与者广播伪造的公钥,并使用伪造的密钥读取那些想要发送给被害用户的加密消息,还可以使用伪造的密钥进行认证。
解决这个问题的方法是 公钥证书 。公钥证书的组成部分是:
- 公钥
- 公钥所有者的用户 ID
- 可信第三方签名
- 第三方一般来说是用户团体所信任的认证中心(Certificate Authority,被称为 CA ),比如政府机构等
- 缺失可信第三方签名的证书被称为为签名证书,由用户软件方产生
- 签名的产生方式是由 CA 利用安全散列函数计算出未签名证书的散列码,并使用自己的私钥对该散列码进行加密,得到一个签名
- 用户可以通过安全渠道将自己的公钥和为签名证书提交给 CA ,并获得签名证书
用户获得带签名的公钥证书之后可以发布这个证书,其他用户在获取该用户的公钥时同时会获取这个证书,可以通过证书中附带的可信签名验证其有效性。验证的过程也是基于公钥加密机制的,即接收者计算证书(不包括 CA 签名)的散列码,并利用已知的 CA 的公钥对证书的签名进行解密,比较二者是否匹配即可。
非对称加密算法
由于公钥加密是非对称的,因此公钥加密体制中的密码算法一般被称为 非对称加密算法 。
RSA
一种分组密码,其明文和密文均是 0 ~ n - 1 之间的整数。
Diffie-Hellman 密钥协商
目的是使两个用户可以安全地交换密钥,以便在后续的通信中用该密钥对消息进行加密。例如,在对称加密中,要求两个通信实体共享一个秘密密钥,此时共享唯一私钥的操作就需要公钥加密保证传输的安全性。
数字签名标准 DSS
只提供数字签名功能,不能用于加密和密钥分发。它使用 SHA-1 算法给出了一种新的数字签名方法,被称为 DSA (数字签名算法,Digital Signature Algorithm)。
椭圆曲线密码学
可以使用比 RSA 短得多的密钥得到相同的安全性(毕竟为了提高安全性,近年来 RSA 算法的密钥长度一直在增加,这是一个不小的负担),但由于针对它的密码分析研究刚刚起步,可信度暂时还不如 RSA 高。
公钥密码系统的应用
公钥密码系统的应用广义上可以分为两类:数字签名、密钥的管理分发。后者的主要应用包括对称密钥分发和密钥加密。不同的密码算法适用于不同的应用。
算法 | 数字签名 | 对称密钥分发 | 密钥加密 |
---|---|---|---|
RSA | ✅ | ✅ | ✅ |
Diffie-Hellman | ❌ | ✅ | ❌ |
DSS | ✅ | ❌ | ❌ |
椭圆曲线 | ✅ | ✅ | ✅ |
数字签名
前面我们提到过私钥加密这种操作模式可以提供认证,数字签名的创建本质就是使用私钥加密模式,对消息的安全散列值进行加密操作,这一步得到的密文称为数字签名,与消息一起发送。消息接收方收到带有签名的消息后,需要计算消息的散列值,并利用消息发送方的公钥对签名进行解密,如果两个散列值相同,则可以确认收到的消息是由可信的发送方发送的。
数字签名本身 不提供机密性 。
密钥管理与分发
针对密钥管理与分发,至少有三个方面使用公钥加密:
- 安全地分发公共密钥
- 使用公钥加密分发密钥
- 包括对称密钥的交换与共享
- 使用公钥加密为消息加密创建临时密钥
- 数字信封 :用于保护消息而不必事先让收发双方拥有相同的密钥
- 假设 Bob 要发送一个机密消息给 Alice ,但他们没有事先共享一个对称的秘密密钥,此时 Bob 可以产生一个随机的一次性对称密钥,用它对消息进行对称加密,再用 Alice 的公钥对一次性密钥进行公钥加密,把消息密文和加密后的一次性密钥发给 Alice 。Alice 收到消息后,用自己私钥对一次性密钥进行解密,再还原出原始的消息明文。
- 数字信封 :用于保护消息而不必事先让收发双方拥有相同的密钥
随机数和伪随机数
基于密码学的大量网络安全算法都使用了随机数,它们对随机数序列提出了两种不一定兼容的要求:
- 随机性
- 传统上,关注数列的随机性是否具有良好的统计性质,一般来说有 分布均匀性 和 独立性 两个准则
- 目前还没有测试方法可以证明数列的独立性,即序列中任何数不能由其他数推导而来的性质
- 不可预测性
- 在相互认证这类应用中,对数列的统计随机性要求不是很高,但是要求产生的随机数序列不可预测(或者说不能从前面的随机数推导出后面的)
- 所谓的“真”随机数序列是通过数列中各个数之间的统计独立性保证的,一般来说很少要求数列一定是真随机
随机数大多由确定的算法生成,因此它们并不是统计随机的,但算法的质量可以保证生成的随机数序列能够通过一定强度的随机性检测,这种数被称为 伪随机数 。
一个真随机数发生器是利用不确定的源来生成随机数,一般来说是测量不可预测的自然过程(如电离辐射效应的脉冲检测器等)。
参考资料:
- Computer Security: Principles and Practice, Third Edition