Crypto-流密码(未完结)
https://lazzzaro.github.io/2020/11/07/crypto-流密码/
RC4
在密码学中,RC4(来自Rivest Cipher 4的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一。
由美国密码学家罗纳德·李维斯特(Ronald Rivest)在1987年设计的。由于RC4算法存在弱点,2015年2月所发布的 RFC 7465 规定禁止在TLS中使用RC4加密算法。
RC4由伪随机数生成器和异或运算组成。RC4的密钥长度可变,范围是[1,255]。RC4一个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钥并产生一个S盒。S盒用来加密数据,而且在加密过程中S盒会变化。
由于异或运算的对合性,RC4加密解密使用同一套算法。
算法
KSA
1 2 3 4 5 6 7 8 for i from 0 to 255 S[i] := i endfor j := 0 for ( i=0 ; i<256 ; i++) j := (j + S[i] + key[i mod keylength]) % 256 swap values of S[i] and S[j] endfor
PRGA
下面i,j是两个指针。每收到一个字节,就进行while循环。通过一定的算法((a),(b))定位S盒中的一个元素,并与输入字节异或,得到k。循环中还改变了S盒(©)。如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文。
1 2 3 4 5 6 7 8 9 10 i := 0 j := 0 while GeneratingOutput: i := (i + 1 ) mod 256 //a j := (j + S[i]) mod 256 //b swap values of S[i] and S[j] //c k := inputByte ^ S[(S[i] + S[j]) % 256 ] output K endwhile
此算法保证每256次循环中S盒的每个元素至少被交换过一次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 def KSA (key ): keylength = len (key) S = range (256 ) j = 0 for i in range (256 ): j = (j + S[i] + key[i % keylength]) % 256 S[i], S[j] = S[j], S[i] return S def PRGA (S ): i = 0 j = 0 while True : i = (i + 1 ) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] K = S[(S[i] + S[j]) % 256 ] yield K def RC4 (key ): S = KSA(key) return PRGA(S) if __name__ == '__main__' : key = 'Key' plaintext = 'Plaintext' def convert_key (s ): return [ord (c) for c in s] key = convert_key(key) keystream = RC4(key) import sys for c in plaintext: sys.stdout.write("%02X" % (ord (c) ^ keystream.next ())) print
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 N = 256 S = [0 ] * N key = 'keykeykey' Key = [0 ] * N t = [] for i in range (N): S[i] = i Key[i] = ord (key[i % len (key)]) j = 0 for i in range (N): j = (j + S[i] + Key[i]) % N S[i], S[j] = S[j], S[i] i = 0 j = 0 for k in range (len (t)): i = (i + 1 ) % N j = (j + S[i]) % N S[i], S[j] = S[j], S[i] t[k] ^= S[(S[i] + S[j]) % N] print (t)print ('' .join(chr (k) for k in t))