RC4算法:
RC4(来自Rivest Cipher 4的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥
基本原理:
生成一个密钥流,然后与密文进行异或。
大致过程:
生成密钥流:
先利用Key生成S盒——The key-scheduling algorithm (KSA)
再利用S盒生成密钥流——The pseudo-random generation algorithm(PRGA)
加密:
将密文与密钥流异或。
解密:
将明文与密钥流异或。
代码实现:
KSA(生成S盒):
#生成一个长度为256的S盒。注!:这是标准的,可以为别的,例如128,但安全会有问题
def KSA(key)
key =list(key)
s_box = list(range(256))
j=0
for i in range(256):j=(j+s_box[i]+ord(key[i%len(key)]))%256s_box[i],s_box[j]=s_box[j],s_box[i]return s_box
PRGA(生成密钥流):
def PRGA(s_box)
res=[]
i=0
j=0
for a in plain:i=(i+1)%256j=(j+S[i])%256s[i], s[j] = s[j], s[i]t=(s[i]+s[j])%256yield s[t]
加密同解密:
def rc4_encrypt (date,key):s = KSA(key)keystream =PRGA(s)encrypted = bytes([byte^next(keystream) for b in date])return encrypted
完整代码:
def KSA(key):key =list(key)s_box = list(range(256))j=0for i in range(256):j=(j+s_box[i]+ord(key[i%len(key)]))%256s_box[i],s_box[j]=s_box[j],s_box[i]return s_boxdef PRGA(s_box):res=[]i=0j=0for a in plain:i=(i+1)%256j=(j+S[i])%256s[i], s[j] = s[j], s[i]t=(s[i]+s[j])%256yield s[t]
def rc4_encrypt (date,key):s = KSA(key)keystream =PRGA(s)encrypted = bytes([byte^next(keystream) for b in date])return encrypted
#密文密钥
key =b"key"
plaintext+b"Hello,world"
#加密
ciphertext = rc4_encrypt(plaintext,key)
#解密
decrypted = rc4_encrypt(ciphertext,key)
例题:
[SWPUCTF 2021 新生赛]简简单单的解密:
import base64,urllib.parse
key = "HereIsFlagggg"
flag = "xxxxxxxxxxxxxxxxxxx"s_box = list(range(256))
j = 0
for i in range(256):j = (j + s_box[i] + ord(key[i % len(key)])) % 256s_box[i], s_box[j] = s_box[j], s_box[i]
res = []
i = j = 0
for s in flag:i = (i + 1) % 256j = (j + s_box[i]) % 256s_box[i], s_box[j] = s_box[j], s_box[i]t = (s_box[i] + s_box[j]) % 256k = s_box[t]res.append(chr(ord(s) ^ k))
cipher = "".join(res)
crypt = (str(base64.b64encode(cipher.encode('utf-8')), 'utf-8'))
enc = str(base64.b64decode(crypt),'utf-8')
enc = urllib.parse.quote(enc)
print(enc)
# enc = %C2%A6n%C2%87Y%1Ag%3F%C2%A01.%C2%9C%C3%B7%C3%8A%02%C3%80%C2%92W%C3%8C%C3%BA
WP:
import base64,urllib.parse
a ="%C2%A6n%C2%87Y%1Ag%3F%C2%A01.%C2%9C%C3%B7%C3%8A%02%C3%80%C2%92W%C3%8C%C3%BA"
a = urllib.parse.unquote(a)
key = "HereIsFlagggg"
s_box = list(range(256))
j = 0
for i in range(256):j = (j + s_box[i] + ord(key[i % len(key)])) % 256s_box[i], s_box[j] = s_box[j], s_box[i]
res = []
i = j = 0
for s in a:i = (i + 1) % 256j = (j + s_box[i]) % 256s_box[i], s_box[j] = s_box[j], s_box[i]t = (s_box[i] + s_box[j]) % 256k = s_box[t]res.append(chr(ord(s) ^ k))
cipher = "".join(res)
print(cipher)