100 行代码手把手带你实现 Feisitel 加密算法
简介
Feistel 加密算法,或者叫做 Feistel 网络,是一种块加密(block cipher)模型,很多常见的加密算法都具有 Feistel 结构,如 DES、blowfish 等。
Feistel 将明文分割成固定大小(block size)的块(如 32bit、64bit),然后对于每个块进行若干轮操作,每轮操作需要用到一个 key,因此总计需要循环轮数个 key。解密时需要用相同的 keys,因此这是一种对称加密算法。
加密步骤
将明文转换为 8-bit 二进制形式
根据块大小(block size)分割成若干个数据块,不足整数块时需要加 padding
生成轮数(rounds)个 key 的 keys 数组
对于每个数据块进行若干轮操作,具体如下:
在每轮操作中都将数据块分成相等的左右两部分(L1, R1)
将右半部分(R1)与 keys[n]进行加密函数 f 运算,记为 f1
然后将 f1 与左半部分进行异或(XOR)操作的结果作为下一轮输入的左半部分(L2)
将本轮左半部分(L1)作为下一轮输入的右半部分(R2)
下一轮的输入为 L2 + R2, 再进行下一轮操作
在最后一轮结束后将左半部分(Ln)和右半部分(Rn)对调(这样可以使用同一个循环进行加密和解密)
解密步骤
将密文使用相同的 keys 进行与加密过程相同的循环,不过 key 的顺序与加密时相反(加密时使用 key[1], key[2], ..., key[n], 解密时使用 key[n], key[n-1], ..., key[1])
组合数据块并按照 8bit 进行分割
根据 ASCII 码转换为明文
Python 实现
首先定义一些变量
生成随机的 keys
定义每一轮循环的操作
加密过程
解密过程
最后测试一下
总结
本文中为了方便演示将 block size 和 key size 设置较小,实际一般会更长,如果不满整个 block 则需要补 padding(用 0 填充)
加密和解密使用相同的循环,但是注意不要忘记需要在加/解密的最后一轮循环后交换左、右部分
动手实现时可以将 round 设为 1 或 2,单步观察每一轮循环的结果
时间复杂度 O(n)
额外空间 O(n)
作者:justMonika
链接:https://juejin.cn/post/7395069382433456147
评论