ssl + 对称加密
聊一下怎么用ssl的接口做对称加密 + 解密。
1. AES
看一段demo
简单的说几个参数
- IV: Initialization Vector, 一般是加密过程初始化产生的随机向量。加密和解密过程需要同一组IV
- key, 密钥,加解密共一个,一般是随机生成的,如果不是协商出来 + 随机的话,基本不安全
- aad, Additional Authenticated Data, 附加认证数据,一般明文,只要保证完整就可以了
- tag, 用于认证加密数据的完整性,一般是encrypto生成的,要在decrypto的时候提供
剩下的就是必要参数了,比如明文和密文。
因此,如果你自定义了一个加密/解密的流,其实你就定义了一个协议。
另外尽量不要使用AES_*
的参数,能用EVP_*
的话就尽量使用后者,因为在内部实现中,会有很多高级指令对运算操作加速
2. iv + key的生成
IV初始向量在CBC,CFB模式下,仅影响前16字节(128位加密方式)的块,推荐使用CTR模式.
2.0 什么是AES
加密算法分可恢复和不可恢复
可恢复的又分对称加密和非对称加密,AES是对称加密
Advanced Encryption Standard(高级加密标准),DES之后的继任者,是一种对称加密算法,密钥长度支持128、192、256位,分别对应AES-128、AES-192、AES-256
2.1 AES的工作模式
1
2
3
4
5
6
+---------+ +------------+ +-----------+ +------------+ +---------+
| | | | | | | | | |
| Plain | --> | AES Encrypt| --> | Transmit | --> | AES Decrypt| --> | Plain |
| Text | | with Key| | | | with Key| | Text |
| | | | | | | | | |
+---------+ +------------+ +-----------+ +------------+ +---------+
一种比较简单的加解密方式,XOR。
2.3 AES的概念
- Block Size: 128 bits
- key size: 128/192/256 bits
- 加密模式: ECB、CBC、CFB、OFB、CTR
- 初始向量: IV
- 填充方式: PKCS5Padding、PKCS7Padding、NoPadding
- 附加消息: AAD
2.3.1 Block Size
首先,block size, AES是一种分组加密, 每次加密的数据块大小是固定的,AES的数据块大小是128位,也就是16字节。这是AES规定的,不可更改的。
2.3.2 Key Size
其次,key size, AES的密钥长度支持128、192、256位,分别对应AES-128、AES-192、AES-256。这是AES的一个特点,也是AES的一个优点,因为密钥长度越长,破解的难度就越大。
算法 | 分组长度 | 密钥长度 | 迭代轮数 |
---|---|---|---|
AES-128 | 128位 | 128 | 10 |
AES-192 | 128位 | 192 | 12 |
AES-256 | 128位 | 256位 | 14 |
越往下,越安全
2.3.3 加密模式
第三,加密模式,基本能分成5种,看wiki
工作模式 | 描述 | 典型应用 |
---|---|---|
ECB (Electronic Codebook) | 每个块独立加密,同样的明文块和密钥产生同样的密文块。 | 不推荐在需要高安全性的系统中使用,因为它不提供严格的数据混淆。 |
CBC (Cipher Block Chaining) | 每个明文块与前一个密文块进行异或操作后,再进行加密。 | 在需要数据完整性的系统中常用,如HTTPS、SSH。 |
CFB (Cipher Feedback) | 一次处理s位,上一块密文作为加密算法的输入单元,产生的伪随机数输出与明文xor作为下一单元的密文 | 面向数据流的通用传输认证 |
OFB (Output Feedback) | 跟CFB类似,加密算法的输入是上一次加密的输出,且使用整个分组 | 噪声信道上的传输 |
CTR (Counter) | 每个明文分组都与一个经过加密的计数器相相xor,对每个后续分组,计数器递增 | 在需要并行处理的系统中常用,如硬盘加密。 |
2.3.4 初始向量
第四,初始向量,IV,Initialization Vector,一般是加密过程初始化产生的随机向量。加密和解密过程需要同一组IV。
假设以CBC为例子的话,在每一个明文块被加密之前,会让明文和密文做xor。IV作为初始化向量,会跟第一个明文块做xor(因为之前没有任何被加密的明文),后续的每一个明文块和它前一个明文块所加密出的密文块相异或。这样能保证密文块的不重
参考一下怎么生成Using Salts, Nonces, and Initialization Vectors
2.3.5 填充方式
因为密钥往往只能对确定长度的数据进行处理加密,数据的长度是不确定的,因此需要填充,一般是对最后一个块做额外的处理,常用的模式就是PKCS5Padding、PKCS7Padding、NoPadding,这个可以通过openssl的接口, EVP_CIPHER_CTX_set_padding
来设置
2.3.6 附加消息
AAD,一般不是应用层会关注的数据,一般是包含在协议里的纯数据,需要保护完整性,但不用加密。
3 GCM
3.1 什么是CTR加密模式
还是分块,但是每次只要知道nonce + counter(一个从0到n的编号) + key就可以了。这个加密模式可以并行执行,但没办法做消息完整性验证。所以得带一个mac(Message Authentication Code)
然后看一乐把
AES模式 | 是否需要tag |
---|---|
ECB | 不需要 |
CBC | 不需要 |
CFB | 不需要 |
OFB | 不需要 |
CTR | 不需要 |
GCM | 需要 |
CCM | 需要 |
3.2 什么是GCM
GCM = GMAC + CTR, 具体算法的逻辑看下wiki