密码学概述
密码学(来自希腊语kryptos,意思是隐藏)一词的核心是指使数据无法被窥探者读取的技术。当然,密码学也可以用于其他目的。密码学包括一系列技术,如验证数据的真实性(检测是否修改)、确定个人或其他实体的身份、确定谁发送了特定消息或创建了特定数据片段、通过网络安全地发送数据、用密码或口令安全地锁定文件等等。
计算机安全中使用的加密主要有两种类型,称为对称密钥加密和非对称密钥加密。
对称密钥加密
对称密钥加密(也称为秘密密钥加密)是大多数人熟悉的密钥的经典用法:使用相同的密钥来加密和解密数据。经典且最容易破解的版本是凯撒密码(以朱利叶斯·凯撒命名),其中消息中的每个字母都被替换为字母表中固定位置数的字母(例如,“a”被“c”替换,“b”被替换为“d”等)。在凯撒密码中,用于加密和解密消息的密钥只是字母表旋转的位数以及旋转的方向。现代对称密钥算法更加复杂并且更难破解。
有许多不同的算法用于对称密钥加密,提供从最低限度到几乎牢不可破的安全性。其中一些算法提供了强大的安全性、易于代码实现以及快速的加密和解密。此类算法对于加密存储在计算机上的文件以保护它们以防未经授权的个人使用计算机等目的非常有用。但它们在从一台计算机向另一台计算机发送消息时用处不大,因为通信通道的两端都必须拥有相同的密钥并且必须保证其安全。此类密钥的分发和安全存储可能很困难,并且可能会造成安全漏洞。
虽然交换或创建对称密钥的安全技术可以在一定程度上克服这个问题(例如 Diffie-Hellman 密钥交换),但随着非对称密钥加密算法的发明,出现了一种用于计算机通信的更实用的解决方案。
常见的现代对称密钥加密算法有 DES,3DES,AES 等
DES
数据加密标准(英语:Data Encryption Standard,缩写为 DES)是一种对称密钥加密算法,1976 年被美国联邦政府的国家标准局确定为联邦资料处理标准,随后在国际上广泛流传开来。
DES 现在已经不是一种安全的加密方法,主要因为它使用的 56 位密钥过短。1999 年 1 月,distributed.net 与电子前哨基金会合作,在 22 小时 15 分钟内即公开破解了一个 DES 密钥。
也有一些分析报告提出了该算法的理论上的弱点,虽然在实际中难以应用。为了提供实用所需的安全性,可以使用 DES 的派生算法 3DES 来进行加密,虽然 3DES 也存在理论上的攻击方法。DES 标准和 3DES 标准已逐渐被高级加密标准(AES)所取代。
3DES
三重数据加密算法(英语:Triple Data Encryption Algorithm,缩写为 TDEA,Triple DEA),或称 3DES(Triple DES),是一种对称密钥加密块密码,相当于是对每个数据块应用三次资料加密标准(DES)算法。由于计算机运算能力的增强,原版 DES 由于密钥长度过低容易被暴力破解;3DES 即是设计用来提供一种相对简单的方法,即通过增加 DES 的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
AES
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),又称 Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于 2001 年 11 月 26 日发布于 FIPS PUB 197,并在 2002 年 5 月 26 日成为有效的标准。现在,高级加密标准已然成为对称密钥加密中最流行的算法之一。
该算法为比利时密码学家 Joan Daemen 和 Vincent Rijmen 所设计,结合两位作者的名字,以 Rijndael 为名投稿高级加密标准的甄选流程。
加密模式
对称加密算法的加密模式是指在对称加密过程中,明文如何被切分、填充和加密,以及密文如何被解密和还原成原始的明文。常见的对称加密算法包括 AES(高级加密标准)和 DES(数据加密标准),它们可以使用不同的加密模式来实现数据的保密性。
虽然加密模式通常应用于对称加密,它亦可以应用于公钥加密,例如在原理上对 RSA 进行处理,但在实用中,公钥密码学通常不用于加密较长的信息,而是使用结合对称加密和公钥加密的混合加密方案。
常见的对称加密模式包括:
- 电子密码本模式(ECB):是最简单的加密模式,将明文分成固定大小的块,然后每个块单独加密。这种模式的问题在于相同的明文块会加密成相同的密文块,可能导致安全性问题。
- 密码分组链接模式(CBC):1976 年,IBM 发明了密码分组链接(CBC,Cipher-block chaining)模式。在 CBC 模式中,每个明文块先与前一个密文块进行异或后,再进行加密。在这种方法中,每个密文块都依赖于它前面的所有明文块。同时,为了保证每条消息的唯一性,在第一个块中需要使用初始化向量。
- 计数器模式(CTR):将一个计数器与明文块进行加密,然后再将结果与明文进行异或操作,从而产生密文。这种模式可以并行处理,并且不需要对明文进行填充,因此在某些情况下更高效。
- 密文反馈模式(CFB):将前一个密文块作为加密器的输入,然后将结果与明文进行异或操作,得到密文。这种模式可以进行流加密,即逐位地进行加密和解密。
- 输出反馈模式(OFB):类似于CFB,但是加密器的输出用于生成密钥流,而不是直接与明文进行异或操作。
这些加密模式的选择取决于应用场景、安全需求和性能要求。在实际应用中,需要根据具体情况选择最合适的加密方式和模式。
对称加密的终端练习
MacOS 自带了一个叫 OpenSSL 的开源加密工具包,提供了一系列的加密算法和安全通信协议的实现,包括 SSL 和 TLS。它由一组函数库和命令行工具组成,可以用于处理数字证书、实现安全通信协议、进行加密和解密等任务。
由于 DES,3DES 目前都不太推荐了,所以这里仅使用 AES 算法演示。
使用 openssl 对明文 helloworld 进行 AES 算法 ECB 模式加密的命令:
1 | echo -n "helloworld" | openssl enc -e -aes-256-ecb -a -pbkdf2 -K 123456 |
会输出如下结果
1 | bnPkNleniCxX5rE1JjnOYg== |
对以上结果解密的命令:
1 | echo "bnPkNleniCxX5rE1JjnOYg==" | openssl enc -d -aes-256-ecb -a -pbkdf2 -K |
对明文 helloworld 进行 aes cbc 加密的命令是:
1 | echo helloworld | openssl enc -e -aes-256-cbc -a -pbkdf2 -K 123456 |
这里 -k 后面的参数 123456 就是用到的密钥。对上面的输出进行解密的命令是:
1 | echo U2FsdGVkX19TcP2WjEKOsVXGblFWLGMJM/1dDgvY/S8= | openssl enc -d -aes-256 |
iOS 中使用对称加密
iOS 系统提供了一个 CommonCrypto 库用于加密解密,生成消息摘要(hash)等功能。
1 |
|
上面的 iOS 代码中使用的加密和解密函数,等价于以下 openssl 终端命令:
加密
1 | echo -n "helloworld" | openssl enc -e -aes-256-cbc -K "3132333435363738313233343536373831323334353637383132333435363738" -iv "30313233343536373839616263646566" -base64 |
解密
1 | echo "dMujh+yeGsbTA0xqdhae4Q==" | openssl enc -d -aes-256-cbc -K "3132333435363738313233343536373831323334353637383132333435363738" -iv "30313233343536373839616263646566" -base64 |
openssl 的 -K 和 -iv 参数的类型是 16 进制编码的字符串。12345678123456781234567812345678 的 16 进制编码就是 3132333435363738313233343536373831323334353637383132333435363738,同样 0123456789abcdef 的 16 进制编码就是 30313233343536373839616263646566
非对称密钥加密
在非对称密钥加密中,不同的密钥用于加密和解密消息。最有用的非对称密钥算法是那些不能从另一个密钥推导出密钥的算法。在这种情况下,一个密钥可以公开,而另一个密钥则保持安全。这种安排通常称为公钥密码术,并且与对称加密相比具有一些明显的优势:消除了向大量用户分发密钥的必要性,并且该算法可用于身份验证以及加密。
第一个广泛使用的公钥算法由 Ron Rivest、Adi Shamir 和 Len Adleman 于 1977 年描述,被称为 RSA 加密,源自其缩写。尽管此后又创建了其他公钥算法,但 RSA 仍然是最常用的。该方法的数学原理超出了本文档的范围,可以在互联网和许多密码学书籍中找到。该算法基于两个大素数及其乘积的数学运算。人们认为它的强度与分解非常大的数的难度有关。以现代数字计算机当前和可预见的速度,在生成 RSA 密钥时选择足够长的素数应该可以使该算法无限期地安全。然而,这一观点尚未得到数学证明,并且快速分解算法或完全不同的破解 RSA 加密的方法是有可能的。此外,如果实用的量子计算机被开发出来,分解大数将不再是一个棘手的问题。
其他公钥算法基于与 RSA 具有同等复杂性的不同数学,包括 ElGamal 加密和椭圆曲线加密。它们的使用类似于 RSA 加密(尽管它们背后的数学原理不同),并且本文档不会进一步讨论它们。
RSA 算法
1977 年三位麻省理工学院的数学家 罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起设计了一种算法,可以实现非对称加密。这个算法用他们三个人的名字命名,叫做 RSA 算法。
RSA 密钥生成过程
在 RSA 算法中,首先选择两个大质数 p 和 q,然后计算他们的乘积 n = p * q。接下来,计算欧拉函数 φ(n) = (p-1)(q-1)。在选择公钥 e 时,需要确保 e 和 φ(n) 互质。
然后找到一个整数 d,使得(e * d)mod φ(n) = 1。这个 d 就是私钥。
RSA 加密和解密
在 RSA 加密过程中,明文 m 经过公钥 e 进行加密得到密文 c ,计算公式为 c = me % n。在 RSA 解密过程中,密文 c 经过私钥 d 进行解密得到明文 m,计算公式为 m = cd % n。
一个问题?在 RSA 算法中,为什么 e 和 φ(n) 互质,d 是 e 的模反元素,就可以保证 Me * d % n = M 呢?我听过某讲师说是基于欧拉定理,但是欧拉定理的推导中是要求 m 和 n 互质的,但是刚刚 RSA 密钥生成过程中并没有要求 m 和 n 互质,只需要 m 小于 n 就够了。
RSA 算法的终端练习
使用 openssl 生成 RSA 私钥的命令:
1 | openssl genrsa -out private_key.pem 2048 |
这个命令会生成一个 2048 位长度的 RSA 私钥,并将其保存在名为 private_key.pem 的文件中。
将私钥转换成对应的公钥,可以使用以下命令:
1 | openssl rsa -pubout -in private_key.pem -out public_key.pem |
现在在当前目录下就会存在两个文件,一个是公钥 public_key.pem,一个是私钥 private_key.pem 。
接下来我们使用这对密钥进行加密解密的演示,先创建一个文件 original.txt 存放明文数据,命令如下:
1 | echo "密码是123456" > original.txt |
使用公钥对 original.txt 文件进行加密并生成一个 encrypted.txt 文件的命令:
1 | openssl pkeyutl -encrypt -in original.txt -out encrypted.txt -pubin -inkey public_key.pem |
可以使用 cat encrypted.txt
查看加密后的结果,发现是一堆乱码,啥也看不懂。。。接下来使用私钥对 encrypted.txt 文件进行解密并生成一个 decrypted.txt 文件:
1 | openssl pkeyutl -decrypt -in encrypted.txt -out decrypted.txt -inkey private_key.pem |
使用 cat decrypted.txt
查看解密后的结果,可以看到跟 original.txt 的内容是一模一样的。
iOS 中使用非对称加密算法
iOS 提供了 Security.framework 框架用于帮助开发者实现各种安全相关的功能。这个框架包含了处理加密、密钥管理、证书、信任策略和安全通信的基本功能。通过使用 Security 框架,开发者可以确保应用程序的数据保护、安全传输和用户身份验证等功能。
1 |
|
Hash 函数
Hash,一般翻译做“散列”,也有直接音译为“哈希”的。哈希函数是一种将任意大小的输入数据转换为固定长度散列值的算法。哈希函数的主要作用是验证数据的完整性和唯一性,可以简单的理解为二进制数据的身份证或者指纹。常见的哈希函数包括 MD5、SHA-1 和 SHA-256 等。
哈希函数的特点:
- 计算速度快
- 将任意长度的数据计算出固定长度的哈希值
- 对相同数据计算得到的结果是不变的
- 具备单向性,无法逆运算
MD5
即 Message Digest 5 的缩写,产生 128 位的哈希值。也就是 32 位 16 进制数。Mac 电脑终端一般自带 md5 命令,可以用于一些简单的计算。例如计算 “12345” 的 md5 值:
1 | md5 -s 12345 |
假设你有两份同名的文件,但是不确定内容是否是一样的。就可以使用 md5 查看两个文件的哈希值。
注意 md5 由于长度较短,目前已经不太安全,因为可以对明文和它的 md5 哈希值建立一个字典,比如 “12345” 的 md5 值是 827ccb0eea8a706c4c34a16891f84e7b 。目前某些解密网站已经建立了这样的字典,如 https://www.cmd5.com/ 所以如果你的需求对安全性要求较高的话,不推荐使用了。但如果是平时用来验证文件的唯一性倒也没什么太大问题。
SHA
SHA 代表安全散列算法(Secure Hash Algorithm),是一种广泛使用的密码学哈希函数,用于生成数据的哈希值。哈希函数将输入数据转换为固定长度的数据串,通常是一串数字和字母的组合,该串称为哈希值或消息摘要。SHA 算法的哈希值长度可以根据具体的 SHA 版本而变化,比如 SHA-1 生成 160 位的哈希值,而 SHA-256 生成 256 位的哈希值。目前主流的 SHA 版本主要是 SHA-256 和 SHA-3。这两个版本都是较新的,并且在安全性和性能方面都得到了广泛认可。
SHA-1
产生 160 位的散列值,目前已经不安全
SHA-2
SHA-256,SHA-384,SHA-512,散列值长度分别是 256 位,384 位,512 位
SHA-3
SHA-3 是 NIST 选定的一种新的哈希算法标准,也称为 Keccak。它是在 SHA-2 之后发布的,与 SHA-2 系列不同,SHA-3 提供了与之前版本不同的设计和性能特性。SHA-3 的最常见变体是 SHA-3-256,生成 256 位的哈希值。
应用场景
- HMAC(Hash-based Message Authentication Code)是一种用于验证消息完整性和真实性的加密方案。
- 拆词搜索
- 版权
- 数字签名
base64 编码
Base64 编码是一种将二进制数据转换成文本数据的编码方式。在 Base64 编码中,每个字符由 64 个字符中的一个表示,因此得名。Base64 编码常用于在网络传输中表示二进制数据,比如在电子邮件中传输附件、在网页中嵌入图片等场景。
Base64 编码的原理是将二进制数据每 6 位转换成一个字符,所以每 3 个字节(24 位)的二进制数据转换成 4 个 Base64 字符。如果原始数据长度不是 3 的倍数,则在末尾补上相应数量的 0,并用 “=” 字符填充以保持长度是 4 的倍数。所以以后看到字符串的末尾是 “=” 字符的时候,它有可能就是 Base64 编码后的字符串。
Base64 编码使用了 64 个字符,通常是大小写字母 a-z、A-Z、数字 0-9,以及两个额外的字符(通常是”+”和”/“)作为基本字符集,不同的实现中有时候会用不同的字符集。
Base64 编码并不是加密算法,因为它可以轻松地被解码还原成原始数据。它的主要作用是在不支持二进制传输的环境中,将二进制数据表示为文本,便于传输和处理。
数字签名
数字签名是一种用于验证数据完整性和身份验证的技术。它使用非对称加密技术,结合了哈希函数和公钥加密算法,以确保数据的完整性、真实性和不可否认性。
数字签名通常由以下步骤组成:
- 创建消息摘要:发送方使用哈希函数(如 SHA-256)生成消息的摘要或哈希值。这个摘要是一个固定长度的字符串,用于代表原始数据的内容。
- 使用私钥签名:发送方使用自己的私钥对消息摘要进行加密,形成数字签名。私钥只有发送方知道,因此只有发送方能够使用私钥进行签名。
- 传输数据:发送方将原始数据与数字签名一起发送给接收方。
- 验证签名:接收方收到数据后,使用发送方的公钥对数字签名进行解密,得到消息摘要。然后,接收方使用相同的哈希函数生成接收到的原始数据的摘要。如果两个摘要匹配,则表明数据未被篡改,签名有效;否则,数据可能已被篡改或签名无效。
数字签名的主要目的是确保数据的完整性和真实性,同时提供身份验证和不可否认性,即发送方不能否认其曾经签署过数据。这使得数字签名在许多领域,如电子商务、数字文档、软件分发等方面发挥了重要作用。
简单的一句话概括,数字签名就是使用私钥对数据的哈希值进行加密。
数字证书
数字证书是一种用于加密和认证网络通信的安全工具。它是由一个权威的数字证书颁发机构(Certificate Authority,CA)签发的一种电子文档,用于确认特定实体的身份信息。数字证书包含了一些重要的信息,包括:
一个数字证书通常包含以下信息:
- 主体信息:证书的主体是该证书所代表的实体,通常是一个个人、组织或网络设备。主体信息通常包括名称、电子邮件地址等。
- 公钥:证书包含了主体的公钥,用于加密和验证数字签名。这个公钥与主体的私钥配对,用于加密和解密通信数据。
- 证书序列号:每个证书都有一个唯一的序列号,用于标识该证书。
- 有效期:证书有一个有效期限,指定了证书的生效时间和到期时间。过期的证书不再可信。
- 数字签名:证书被 CA 用其私钥签名,以确保证书的真实性和完整性。客户端可以使用 CA 的公钥来验证数字签名。
- 颁发者信息:指定了颁发该证书的 CA 的信息。
- 扩展信息:可能包含一些其他信息,例如用途、策略等。
数字证书在网络通信中广泛用于安全连接的建立,例如 HTTPS(安全的HTTP)、SSL/TLS等。通过验证数字证书的真实性,可以确保与远程服务器之间的通信是安全的,并且可以防止中间人攻击等安全威胁。