RC4算法是一种流密码(面向字节操作),密钥长度可变(根据明文长度生成密钥流)
RC4加密流程:
1,初始化状态数组S:长度256字节,每个S[i] 为1个字节,S[i]的值为 0-255
2,初始化临时数组T:T的长度为256字节,每个T[i]为1个字节,
首先生成一个密钥数组Key, Key的长度为1~256字节(随机),每个Key[i] 为1个字节,并且每个Key[i] 的值为随机生成的;
然后将数组Key中的每个Key[i]轮流并且循环放入数组 T,比如Key[]=1,2,3,4,5 ,则放入数组T:T[] =1,2,3,4,5,1,2,3,4,5…1,2,3,4,5,1,2 将数组T填满,这样数组 T 完成了初始化,又具有随机性;
3,初始置换数组 S :通过初始化后的T,和一个变量 j=0,打乱数组 S,使 S具有随机性:
通过对于每一个S[i],通过 j = (j + S[i] + T[I]) mod 256 ,交换 S[i] 和 S[j] 的值;
关于这一步我的理解:因为初始化后的数组T 具有随机性,因此将T元素加入获得S[j]并置换S[i] 和S[j] ,使得数组S 伪随机;
4,生成密钥流KeyStream:首先通过获取明文长度,决定生成与明文等长的密钥流,
通过对每个S[i],j=0,j=(j+S[i]) mod 256将S[i]与S[j] 置换,当i>255,回到S[0],再重复置换操作:
j,t = 0,0
for i in range(txtlen): // txtlen 为明文长度,通过循环,生成等长的密钥流
i = i mod 256 //通过mod 256 ,保证后续对数组S的重复操作
j = (j+S[i]) mod 256
tmp = S[i]
S[i] = S[j] //置换S[i] 与S[j]
S[j] = tmp
t = (S[i] + S[j]) mod 256
KeyStream.append(S[t]) //S[t]为 密钥流中的一位
关于这一步我的理解:假设一个盒子叫S,里面放着一排256个写着从 0-255 号数的小球,并且这个256个小球是先前打乱的,现在你需要从S盒中摸出第一个(i), 和通过公式 j = (j+S[i]) mod 256 得到的第 j 个,将球上的号码记下并通过公式 t = (S[i] + S[j]) mod 256 得出号码 t,那你再去摸出第t个小球,上面的号码S[t]就是密钥流中的一位,并且你把第一个(i)小球和第j个小球交换一下再放回S盒,然后重复刚刚的步骤去摸第二个(i)和第j个以此类推,直到你重复这个步骤 txtlen次; 注:当你摸到第256个(即最后一个),但是你还没做完txtlen次,那么你下一次摸球就是回到第一个开始,这个就是对应的对数组S的重复操作;
贴上参考代码,如有不对,请多指教^-^:
#encoding = utf-8
import random
# 初始化向量 S
def init_S():
global S
for i in range(256):
S.append(i)
# 初始化向量 T
def init_T():
global Key,T
keylen = random.randint(1,256)
for i in range(keylen):
index = random.randint(0,61) #获取随机的临时密钥Key
Key.append(WordList[index])
for i in range(256):
tmp = Key[i % keylen] #初始化向量T
T.append(tmp)
# 初始置换 S[i]
def swap_S():
global S,T
j = 0
for i in range(256):
j = (j+S[i]+ord(T[i])) % 256
tmp = S[i]
S[i] = S[j]
S[j] = tmp
# 密钥流生成
def Get_KeyStream():
global S,text,KeyStream
txtlen = len(text)
j,t = 0,0
for i in range(txtlen):
i = i % 256
j = (j+S[i]) % 256
tmp = S[i]
S[i] = S[j]
S[j] = tmp
t = (S[i] + S[j]) % 256
KeyStream.append(S[t])
# 加密 & 解密
def Get_code():
global PlainText,CryptoText,KeyStream,text
for i in range(len(text)):
CryptoText += chr(ord(text[i]) ^ KeyStream[i]) # 加密
for i in range(len(text)):
PlainText += chr(ord(CryptoText[i]) ^ KeyStream[i]) # 解密
print('''[+]=================开始加密==================''')
print("[+]你的密文---------->",CryptoText)
print('''[+]=================开始解密==================''')
print("[+]你的明文---------->",PlainText)
if __name__ == '__main__' :
T,S,Key = [],[],[]
PlainText,CryptoText,KeyStream = '','',[]
WordList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" # 用于生成临时密钥 Key
print('''
——————— ———————— ——————
| —— \ / _____| / | |
| |__) | | / / —— | |
| __ / | | / |_| | | ^__^ is easy ~, that right ?
| | \ \ | |_____ |______| |
|__| \__\ \________| |_|
██████╗ ██████╗██╗ ██╗ ███╗ ███╗ ██╗███████╗ ███████╗ █████╗ ███████╗██╗ ██╗
██╔══██╗██╔════╝██║ ██║ ██╔██╗ ██╔██╗ ██║██╔════╝ ██╔════╝██╔══██╗██╔════╝╚██╗ ██╔╝
██████╔╝██║ ███████║ ╚═╝╚═╝ ╚═╝╚═╝ ██║███████╗ █████╗ ███████║███████╗ ╚████╔╝
██╔══██╗██║ ╚════██║ ██║╚════██║ ██╔══╝ ██╔══██║╚════██║ ╚██╔╝
██║ ██║╚██████╗ ██║ ███████╗ ██║███████║ ███████╗██║ ██║███████║ ██║
╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚══════╝ ╚═╝╚══════╝ ╚══════╝╚═╝ ╚═╝╚══════╝ ╚═╝
''')
text = input("[+]please input you Plaintext here : ")
init_S()
init_T()
swap_S()
Get_KeyStream()
Get_code()
代码运行正确的截图: