RC4

算法 · 03-21 · 88 人浏览

一、RC4算法简介

密码学中,RC4(来自 Rivest Cipher 4 的缩写)是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4 是有线等效加密(WEP)中采用的加密算法,也曾经是 TLS 可采用的算法之一。

RC4算法由Ron rivest于1987年设计出的一种对称加密算法,其加密密钥和解密密钥是相同的,加密和解密过程也相同。

​ 属于对称加密算法中的流密码加密算法,流密码不对明文数据进行分组,而是用密钥生成与明文一样长短的密码流对明文进行加密。密钥长度可变,面向字节操作,是以一个足够大的表s为基础,对表进行非线性变换,产生密钥流。

  • 加密:原文和Keystream进行异或得到密文
  • 解密:密文和Keystream进行异或得到原文

二、加密过程

Pasted image 20231212141652.png

1.密钥调度算法KSA(Key Scheduling Algorithm)(初始化)

(1)对S表进行线性填充(一般为256字节,用来作为密钥流生成的种子1)
Pasted image 20231212141704.png

(2)用种子密钥(就是我们的秘钥)循环填充另一个256字节的K表(用来作为密钥流生成的种子2)

如果输入长度大于等于256个字节,则进行截取

如果输入长度小于256个字节,则进行轮转,直到填满

例如输入密钥的是1,2,3,4,5 , 那么填入的是1,2,3,4,5,1,2,3,4,5,1,2,3,4,5........

(3)用K表S表进行初始置换(用来打乱初始种子1)

初始化代码:

void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函数

{

    int i =0, j = 0;

    char k[256] = {0};

    unsigned char tmp = 0;

    for (i=0;i<256;i++) {

        s[i] = i;

        k[i] = key[i%Len];

    }

    for (i=0; i<256; i++) {

        j=(j+s[i]+k[i])%256;

        tmp = s[i];

        s[i] = s[j]; //交换s[i]和s[j]

        s[j] = tmp;

    }

 }

  

void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密

{

    int i = 0, j = 0, t = 0;

    unsigned long k = 0;

    unsigned char tmp;

    for(k=0;k<Len;k++) {

        i=(i+1)%256;

        j=(j+s[i])%256;

        tmp = s[i];

        s[i] = s[j]; //交换s[x]和s[y]

        s[j] = tmp;

        t=(s[i]+s[j])%256;

        Data[k] ^= s[t];

     }

}

通过分析初始化代码,可以看出初始化代码中,对字符数组 s 进行了初始化赋值,且赋值分别递增。之后对 s 进行了256 次交换操作。
通过识别初始化代码,可以知道 rc4 算法。

其伪代码表示为:

初始化长度为 256 的 S 盒。第一个 for 循环将 0 到 255 的互不重复的元素装入 S 盒。第二个 for 循环根据密钥打乱 S 盒。

//从第零个字节开始,执行256次,保证每个字节都得到处理

for i from 0 to 255

     S[i] := i

 endfor

 j := 0

 for( i=0 ; i<256 ; i++)

     j := (j + S[i] + key[i mod keylength]) % 256

     swap values of S[i] and S[j]

 endfor
 ```

## 2.伪随机数生成算法(PRGA)

- 为每个待加密字节生成一个伪随机数,用来异或
- 表S一旦完成初始化,种子密钥就不再被使用

 i := 0

 j := 0

 while GeneratingOutput:

     i := (i + 1) mod 256   //a

     j := (j + S[i]) mod 256 //b

     swap values of S[i] and S[j]  //c

     k := inputByte ^ S[(S[i] + S[j]) % 256]

     output K

 endwhile


上面 i,j 是两个指针。每收到一个字节,就进行 while 循环。通过一定的算法((a),(b))定位 S 盒中的一个元素,并与输入字节异或,得到 k。循环中还改变了 S 盒(©)。
如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文。

经过上述步骤后,得到和明文长度相同的密钥流

# 三、python实现
RC4加解密脚本如下:

**#coding=gbk(有些题目的密文的16进制字节码超出了utf-8编码范围,要加上这条,使用gbk,才能正确得到flag)**

import base64

def rc4_setup(key):

"""RC4初始化"""
if isinstance(key, str):
    key = key.encode()

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]

return S

def rc4_crypt(data, key):

"""RC4加解密"""
if isinstance(data, str):
    data = data.encode()

S = rc4_setup(key)
i, j = 0, 0
res = []
for byte in data:
    i = (i + 1) % 256
    j = (j + S[i]) % 256
    S[i], S[j] = S[j], S[i]
    res.append(byte ^ S[(S[i] + S[j]) % 256])

return bytes(res)

def rc4_encrypt(data, key):

"""RC4加密"""
return rc4_crypt(data, key)

def rc4_decrypt(data, key):

"""RC4解密"""
return rc4_crypt(data, key)

def rc4_hex(key_hex, data_hex):

"""RC4加解密(16进制)"""
key = bytes.fromhex(key_hex)
data = bytes.fromhex(data_hex)
res = rc4_crypt(data, key)
return res.hex()

def rc4_encrypt_base64(data, key):

"""RC4加密并转换为base64格式"""
encrypted_data = rc4_encrypt(data, key)
return base64.b64encode(encrypted_data).decode()

def rc4_decrypt_base64(data, key):

"""base64格式解码后RC4解密"""
encrypted_data = base64.b64decode(data)
return rc4_decrypt(encrypted_data, key).decode()

if name == '__main__':

plaintext = b'Thisismessage'
key = b'password123'

# RC4加密
ciphertext = rc4_encrypt(plaintext, key)
print("RC4加密", ciphertext)

# RC4解密
decrypted_text = rc4_decrypt(ciphertext, key)
print("RC4解密", decrypted_text)

# 16进制数据的RC4加解密
ciphertext_hex = rc4_hex(key.hex(), plaintext.hex())
print("16进制数据的RC4加密:", ciphertext_hex)

decrypted_text_hex = rc4_hex(key.hex(), ciphertext_hex)
print("16进制数据的RC4解密:", decrypted_text_hex)

# base64数据的RC4加解密
ciphertext_base64 = rc4_encrypt_base64(plaintext, key)
print("base64数据的RC4加密:", ciphertext_base64)

decrypted_text_base64 = rc4_decrypt_base64(ciphertext_base64, key)
print("base64数据的RC4解密:", decrypted_text_base64)


  [1]: https://blog.equinox.chat/usr/uploads/2024/03/813754543.png
python 算法 加密 算法实现 解密 RC4
Theme Jasmine by Kent Liao