关于aes:AES加解密使用总结

23次阅读

共计 2049 个字符,预计需要花费 6 分钟才能阅读完成。

AES

AES, 高级加密规范, 是采纳区块加密的一种规范, 又称 Rijndael 加密法. 严格上来讲, AES 和 Rijndael 又不是齐全一样, AES 的区块长度固定为 128 比特, 秘钥长度能够是 128, 192 或者 256. Rijndael 加密法能够反对更大范畴的区块和密钥长度, Rijndael 应用的密钥和区块长度均能够是 128,192 或 256 比特. AES 是对称加密最风行的算法之一.

咱们不去探讨具体的 AES 的实现, 因为其中要使用到大量的高等数学常识, 单纯的理解 AES 流程其实也没什么意义(没有数学根底难以了解), 所以咱们明天着重来总结一些应用过程中的小点.

加密模式 – ECB, CBC

当然了分组明码的加密模式不仅仅是 ECB 和 CBC 这两种, 其余的咱们暂不波及.

下面说的 AES 是一种区块加密的规范, 那加密模式其实能够了解为解决不同区块的形式和分割.

ECB

ECB 能够看做最简略的模式, 须要加密的数据依照区块的大小分为 N 个块, 并对每个块独立的进行加密

此种办法的毛病在于同样的明文块会被加密成雷同的密文块, 因而, 在某些场合, 这种办法不能提供严格的数据保密性. 通过上面图示例子大家就很容易明确了

CBC

咱们的我的项目中应用的就是这种模式, 在 CBC 模式中, 每个明文块与前一个块的加密后果进行异或后, 在进行加密, 所以每个块的加密都依赖后面块的加密后果的, 同时为了保障第一个块的加密, 在第一个块中须要引入初始化向量 iv.

CBC 是最罕用的模式. 他的毛病是加密过程只能是串行的, 无奈并行, 因为每个块的加密要依赖到前一个块的加密后果, 同时在加密的时候明文中的轻微扭转, 会导致前面所有的密文块都发生变化. 但此种模式也是有长处的, 在解密的过程中, 每个块的解密依赖上一个块的加密后果, 所以咱们要解密一个块的时候, 只须要把他后面一个块也一起读取, 就能够实现本块的解密, 所以这个过程是能够并行操作的.

填充模式

AES 加密每个块 blockSize 是 128 比特, 那如果咱们要加密的数据不是 128 比特的倍数, 就会存在最初一个分块有余 128 比特, 那这个块怎么解决, 就用到了填充模式. 上面是罕用的填充模式.

PKCS7 / PKCS5

PKCS7 可用于填充的块大小为 1 -255 比特, 填充形式也很容易了解, 应用需填充长度的数值 paddingSize 所示意的 ASCII 码 paddingChar = chr(paddingSize)对数据进行冗余填充. (前面有解释)

PKCS5 只能用来填充 8 字节的块

咱们以 AES(128)为例, 数据块长度为 128 比特, 16 字节, 应用 PKCS7 填充时, 填充长度为 1 -16. 留神, 当加密长度是 16 整数倍时, 反而填充长度是最大的, 要填充 16 字节. 起因是 “PKCS7” 拆包时会按协定取最初一个字节所表征的数值长度作为数据填充长度, 如果因实在数据长度恰好为 16 的整数倍而不进行填充, 则拆包时会导致实在数据失落.

举一个 blockSize 为 8 字节的例子

| DD DD DD DD DD DD DD DD | DD DD DD DD 04 04 04 04 |

第二个块中有余 8 字节, 差 4 个字节, 所以用 4 个 4 来填充

严格来讲 PKCS5 不能用于 AES, 因为 AES 最小是 128 比特(16 字节), 只有在应用 DES 此类 blockSize 为 64 比特算法时, 思考应用 PKCS5

联合我的项目实际

咱们的我的项目最开始加解密库应用了 CryptoSwift, 起初发现有性能问题, 就改为应用 IDZSwiftCommonCrypto.

这里咱们联合我的项目中边下边播边解密来提一个点, 具体的能够参考之前写的 边下边播的总结. 因为播放器反对拖动, 所以咱们在拖拽到一个点, 去网络拉取对应数据时, 应做好 range 的修改, 个别咱们都会以 range 的 start 和 end 为基准, 向前后找到蕴含这个 range 的所有块范畴. 打比方说咱们须要的 range 时 10-20, 这是咱们应该修改 range 为 0 -31, 因为终点 10 在 0 -15 中, 20 在 16-31 中. 这是惯例的 range 修改.(第一步 找 16 倍数点).

然而在理论中, 咱们申请一段数据时, 还波及到解密器的初始化问题, 如果咱们是申请的 0 -31 的数据, 因为是从 0 开始, 所以咱们的解密器只须要用 key 和初始的 iv 来进行初始化, 那如果通过了第一步的根本 range 修改后, 咱们申请的数据不是从 0 开始, 那咱们则还须要持续往前读取 16 个字节的数据, 举个例子, 通过第一步修改后的 range 为 16-31, 那咱们应该再往前读取 16 字节, 应该是要 0 -31 这 32 个字节数据, 拿到数据后, 应用前 16 个字节 (上一个块的密文) 当做 iv 来初始化解密器.

还有一个要留神的点是, 数据解密的过程中, 还有可能会吞掉前面 16 个字节的数据, 我临时没看源码, 不晓得具体因为什么, 所以保险起见, 咱们的 range 最好是再向后读取 16 个字节.

参考

感激浏览

参考资料

https://zh.wikipedia.org/zh-c…
https://segmentfault.com/a/11…
https://ithelp.ithome.com.tw/…

正文完
 0