一、概述
RC4是使用最广泛的一种流密码,通过算法逐字节加密。也是对称密码,加密和解密的秘钥相同。
RC4 是一个典型的基于非线性数组变换的序列密码。它以一个足够大的数组为基础,对其进行非线性变换,产生密钥序列,一般把这个大数组称为 S盒。RC4的S盒大小随参数n的值变化而变化,每个元素n比特。
RC4 包含两个处理过程:一个是密钥调度算法(KSA,Key-Scheduling Algorithm),用来置乱S盒的初始排列;另一个是伪随机生成算法(PRGA,Pseudo RandomGeneration Algorithm)用来输出随机序列并修改S的当前排列顺序
Ron Rivest 在1987年提出RC4加密方法,但他并没有公开,因为RC4是商业机密,不公开加密规则可以提高保密性,但在1994年一位匿名人士公开了RC4的加密规则,之后被广泛应用。然后在2003年和2013年发现严重漏洞。
RC4是一种在电子信息领域加密的技术手段,用于无线通信网络,是一种电子密码,只有经过授权的用户才能享受该服务,使用 64 位或 128 位密钥大小。
二、特点
1.优点:
- 运算速度快
- 秘钥可变
- 不占用内存
- 流密码编码能力强,易于实现
- 面向字节操作
2.缺点:
三、加密
1.初始化S盒(密钥流生成的种子)
S盒是一个256字节的字符型数组,使用for循环将0-255不重复的输入S盒中
# 初始化S盒
def init_S():
global S
for i in range(256): # 将0-255无重复地放入S盒中
S.append(i)
2.初始化T盒
T和是一个256字节的字符型数组,使用for循环将秘钥中填充到T盒中。如果key的长度大于256,则进行截取,则循环填充,如果key的长度等于256,则直接赋值给T盒。
# 初始化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)
3.S盒的初始置换
使用T盒将S[i]与S盒中的另一个数进行替换,保证S盒的搅乱是随机的。
# KSA
# 初始置换 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
4.使用PRGA(为随机数生成算法)生成密钥流
PRGC为每一个待加密字节生成伪随机数,表S一旦完成初始化,种子密钥就不再被使用
# PRGA
# 密钥流生成
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])
5.加密&解密
将key的值与明文/密文字节异或。
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)
四、注意
- 由于RC4算法加密是采用的xor,所以,一旦子密钥序列出现了重复,密文就有可能被破解。所以必须对加密密钥进行测试,判断其是否为弱密钥。
- 为了保证安全强度,目前的
RC4
至少使用128
位密,以防止穷举搜索攻击
五、python脚本
# encoding = utf-8
import random
# 初始化S盒
def init_S():
global S
for i in range(256): # 将0-255无重复地放入S盒中
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)
# KSA
# 初始置换 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
# PRGA
# 密钥流生成
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
text = input("[+]please input you Plaintext here : ")
init_S()
init_T()
swap_S()
Get_KeyStream()
Get_code()