rc4笔记

  1. 原理
  2. 加密与解密脚本
    1. 加密
    2. 解密

原理

1
2
RC4产生足够的随机密钥流,与明文进行异或
(流密码)
  • 256字节的状态向量S= {0,1,…,255},用比特字节表示为S= {00000000, 00000001, ….,11111111}。
  • 用一个可变长度为1256字节(88048位)的密钥来初始化256字节的状态向量S={S[0], S[1], …, S[255]},任何时候,S都包含0~255的8位无符号数的排列组合。
  • 加密和解密时,密码流中的每一个字节k由S产生,通过系统的方式随机从S的256个元素中选取一个。每产生一个字节k,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
<1>S向量原状态
s=[0,1,2,3,……,255]
用2进制字节表示为
s=[00000000,00000001,00000010,……,11111111]

<2>创建临时向量T(256位),如果密钥K的长度为256位,则直接将K赋给T,否则一直重复复制K,直到填满256位的向量T。
伪代码:
for i=0 to255 do:
s[i]=i;
T[i]=k[i mod keylen]

<3>接下来使用T向量来产生S的初始排列。
这个过程从S[0]开始一直处理到S[255],同时对每个S[i],根据T[i]指定的方案将S[i]与S的另一个元素进行交换
伪代码:
j=0;
for i to 255 do:
j= (j+s[i]+T[i]) mod 256;
Swap(s[i],s[j]);
由于上述过程对S的唯一操作就是元素交换,因此S仍然是包含0~255所有元素的排列组合。

<4>密码流的产生
一旦S向量的初始排列完成后,密钥就不再被使用。接下来就是使用S自身来不断输出伪随机密码流的过程了
伪代码:
i,j=0;
while(True):
i = (i + 1) mod 256; //i 不断从0~255循环
j = (j + S[i] ) mod 256;
Swap (S[i], S[j]); //每产生一个k都重新排列S
t = (S[i] + S[j]) mod 256;
k = S[t]; //获取S中的一个随机元素作为密码流字节

<5>加密。
将步骤四中获得的随机字节k与明文的下一字节做异或运算,产生的字节即为对应的密文字节。
解密过程:由于加密只是使用密码流对明文做了异或运算,因此解密过程只需要使用相同步骤产生密码流并对密文进行同样的异或运算即可得到加密前的明文。

加密与解密脚本

加密

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
42
43
# coding=utf-8
from base64 import b64encode

def s_box_a():#生成sbox
s=[]
for i in range(256):
s.append(i)
return s

def key_padding(key):# 填充密钥
k=[0]*256
for i in range(256):
k[i]=key[(i)% len(key)]
return k

def s_box(s,key):#sbox与密钥混合
j=0
for i in range(256):
j=(j+s[i]+ord(key[i]))%256
s[j],s[i]=s[i],s[j]
return s

def main():
#加密
messages=raw_input("please enter message:")#输入明文
key1=raw_input("please enter key:")#输入密钥
key=[]
for i in range(len(key1)):
key.append(key1[i])
key=key_padding(key)
sbox=s_box(s_box_a(),key)
i=j=0
c=""
for x in range(len(messages)):
i = (i+1)%256
j = (j+sbox[i])%256
sbox[i],sbox[j]=sbox[j],sbox[i]
t=(sbox[i]+sbox[j])%256
c+=chr(ord(messages[x])^sbox[t])
print b64encode(c)

if __name__=='__main__':
main()

解密

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
42
43
# coding=utf-8
from base64 import b64decode

def s_box_a():#生成sbox
s=[]
for i in range(256):
s.append(i)
return s

def key_padding(key):# 填充密钥
k=[0]*256
for i in range(256):
k[i]=key[(i)% len(key)]
return k

def s_box(s,key):#sbox与密钥混合
j=0
for i in range(256):
j=(j+s[i]+ord(key[i]))%256
s[j],s[i]=s[i],s[j]
return s

def main():
#解密
cipher=b64decode(raw_input("please enter cipher:"))#输入密文
key1=raw_input("please enter key:")#输入密钥
key=[]
for i in range(len(key1)):
key.append(key1[i])
key=key_padding(key)
sbox=s_box(s_box_a(),key)
i=j=0
m=""
for x in range(len(cipher)):
i = (i+1)%256
j = (j+sbox[i])%256
sbox[i],sbox[j]=sbox[j],sbox[i]
t=(sbox[i]+sbox[j])%256
m+=chr(ord(cipher[x])^sbox[t])
print m

if __name__=='__main__':
main()

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1259742453@qq.com

💰

×

Help us with donation