rc4加解密
原理
流密码加密算法,
通俗来讲,就是使用一个伪随机字节流和明文按位异或实现加密
密文与密钥流再一次异或即可还原明文,实现解密
Key —> KSA —> S数组 —> PRGA —> Keystream
↓
Plaintext --> XOR with Keystream --> Ciphertext
Ciphertext --> XOR with same Keystream --> Plaintext
- key:一个任意长度的密钥,作为生成密钥流的基础
- KSA:(Key Scheduling Algorithm,密钥调度算法)使用密钥初始化一个256字节的状态数组S,S的状态是动态变化的。
S = list(range(256)) # S = [0, 1, 2, ..., 255]
j = 0
for i in range(256):
j = (j + S[i] + key[i % keylen]) % 256
swap(S[i], S[j])
- PRGA:(Pseudo-Random Generation Algorithm,伪随机生成算法)基于状态数组S,逐字节生成随机密钥流
i = j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
swap(S[i], S[j])
K = S[(S[i] + S[j]) % 256] # keystream
yield K
状态数组S与S盒
- 状态数组S
- 本质是一个由密钥初始化,并在每轮keystream生成中不断被打乱
- 可以理解为一个状态机
- 常用于流密码加密
- S盒(Substitution Box)
- 本质上是一个固定的替换表
- 常用于分组加密算法,如
AES
、DES
示例
def ouc_KSA(key):
"""
Key Scheduling Algorithm (KSA)
通过密钥初始化状态数组 S(长度为 256 的排列)
"""
key_length = len(key)
S = list(range(256)) # 初始化 S 为 [0, 1, 2, ..., 255]
j = 0
for i in range(256):
# 密钥的每个字节循环使用,打乱 S
j = (j + S[i] + key[i % key_length]) % 256
S[i], S[j] = S[j], S[i] # 交换 S[i] 和 S[j]
return S
def ouc_PRGA(S):
"""
Pseudo-Random Generation Algorithm (PRGA)
生成伪随机字节流 keystream
"""
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # 交换 S[i] 和 S[j]
K = S[(S[i] + S[j]) % 256] # 输出一个字节
yield K
def ouc_rc4(key, data):
"""
RC4 加密或解密函数
key: 字符串密钥
data: 待加密或解密的字符串
"""
# 将密钥转换为字节整数列表
key = [ord(c) for c in key]
S = KSA(key) # 初始化状态数组 S
keystream = PRGA(S) # 创建 keystream 生成器
# 将明文/密文与 keystream 每字节异或
result = []
for char in data:
k = next(keystream) # 获取一个 keystream 字节
result.append(chr(ord(char) ^ k)) # 异或并转成字符
return ''.join(result)