RC4加密算法与逆向工程

Posted by LXH on May 14, 2025

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)
    • 本质上是一个固定的替换表
    • 常用于分组加密算法,如AESDES

      示例

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)

rc4加密算法逆向工程