1、序列密码
在对称加密中一般分为分组密码(block cipher)和序列密码(stream cipher),两者最大的区别就是在加密那一块,分组是对一组(一般64位)进行加密,而序列则是对一位或字符加密。
1.1 RC4密码
RC4密码大致过程就是:
-
首先由用户输入任意长度的秘钥K ,一个初始数组S[255]={0, 1, 2,…,255}
-
然后初始化一个种子秘钥 T ,将秘钥 K 的值按位循环赋给T,直到填满T为止。
-
用种子秘钥 T 对 S 表进行初始置换,得到置换后的 S 表。
代码如下:
S = [] T = [] def stream_init(main_key): """ 1、初始化 :parmas main_key: 初始化表 S 和 T,用于后续加密或解密 """ global S, T S = [i for i in range(256)] T = [main_key[i%len(main_key)] for i in range(256)] # 256位 # 对S表进行置换 j = 0 for i in range(256): j = (j + S[i] + ord(T[i])) % 256 S[i], S[j] = S[j], S[i] 复制代码
-
接下来就是从 S 表中持续获取到不同的一位秘钥(核心:不断进行S表置换),然后与明文中的一位进行异或运算,就得到一位密文。同理获取到的一位秘钥与密文中的一位进行异或运算,将得到一位明文。
def deal_txt(text): """ 2、处理明文→密文或者密文→明文 :param text: 明文或者是密文 :return: 明文加密或密文解密 """ i, j = 0, 0 a_text = '' # 返回处理后的字符串 for each_t in list(text): # 遍历每位要处理的字符 i = (i + 1) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] # 对S表进行置换 t = (S[i] + S[j]) % 256 k1 = S[t] # k1 就是经过置换后得到的一位秘钥 a_text += chr((ord(each_t) ^ k1)) # 将明文与k1的异或值unicode,转成str字母,然后拼接到a_text中。 return a_text 复制代码
-
对明文中的每一位都和秘钥进行异或操作得到一位密文,然后拼接起来就是最终返回的密文。
if __name__ == '__main__': plaintext = 'zhang' key = 'fwefew' print(f"明文:{plaintext}, 秘钥:{key}") stream_init(key) cipher_txt = deal_txt('zhang') stream_init(key) plaintext2 = deal_txt(cipher_txt) print(f"密文:{cipher_txt}, 解密后明文:{plaintext2}") # 明文:zhang, 秘钥:fwefew # 密文:å¦àÔ, 解密后明文:zhang 复制代码
将加密后的结果与官方RC4加密结果做了对比,发现是一样的,没毛病。这里注意:官方的RC4返回的结果是用16进制表示的,而我的是用字符表示的,其实本质上都是一样的。
2、费马小定理
定理:如果 p 是一个素数,且 a 不是 p 的倍数,那么有
证明费马小定理:
证明方法有很多,其中使用同余性质的方法证明是最精简的。
首先取一个素数 p ,设小于p的数 ,有
设集合
设集合
这里需要证明 Y 的元素不为零且互不相等,至于为什么等下面揭晓。
-
a 不是 p 的倍数推出 ,另外根据取模运算中的乘法运算有:
© 版权声明文章版权归作者所有,未经允许请勿转载。THE END
喜欢就支持一下吧
相关推荐