RC4其实在 CTF 中的 RE 方向考的比较多,但是作为密码手还是需要学习了解一下的。
概念
RC4是一种流密码,它具有运算速度快、实现简单、占用资源少的特点,广泛应用于早期的 WEP、TLS 等协议中。
它是一种对称密码,其加密解密所使用的密钥是相同的,且密钥长度可变,范围是 1~255。
算法
算法主要由两部分组成:
S 盒初始化(KSA)
S 盒是一个长度为 256 的字节数组(S[0]~S[255]),KSA 的作用是用密钥对 S 盒进行置乱,使其具备随机性:
- 步骤 1:初始化 S 盒,令 S[i] = i(i 从 0 到 255);
- 步骤 2:初始化另一个临时数组 T(长度也为 256),将密钥 Key 循环填充到 T 中,则
T [i] = Key [i % len (Key)];
- 步骤 3:置乱 S 盒:维护一个索引变量 j=0,遍历 i 从 0 到 255,执行:
j = (j + S[i] + T[i]) % 256和交换。
1 2 3 4 5 6 7 8
| int i,j=0; for(i = 0;i < 256;i++) //创建并初始化S S[i] = i; for(i = 0;i < 256;i++) { j = (j+S[i]+T[i%len(T)])%256; swap(S[i],S[j]); }
|
密钥流生成(PRGA)
PRGA 基于置乱后的 S 盒,生成与明文长度相同的密钥流:
1 2 3 4 5 6 7 8 9 10
| int i=0,j=0; int m,key; for(m=0;m<L;m++) //L为明文字节长度 { i=(i+1)%256; j=(j+S[i])%256; Swap(S[i],S[j]) key=S[(S[i]+S[j])%256]; flag[m]^=key; }
|
加解密代码实现
RC4 的加解密的密钥和算法都是相同的。
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
| def rc4(data: bytes, key: bytes) -> bytes: S = list(range(256)) j = 0
for i in range(256): j = (j + S[i] + key[i % len(key)]) % 256 S[i], S[j] = S[j], S[i]
i = j = 0 result = bytearray() for byte in data: i = (i + 1) % 256 j = (j + S[i]) % 256 S[i], S[j] = S[j], S[i] K = S[(S[i] + S[j]) % 256] result.append(byte ^ K)
return bytes(result)
if __name__ == "__main__": key = b"TooManyEmojiButWhatIsNext?" plaintext = b"SiestaTime" ciphertext = rc4(plaintext, key) print("Ciphertext (hex):", ciphertext.hex())
decrypted = rc4(ciphertext, key) print("Decrypted:", decrypted.decode())
|