RC4详解

RC4详解

过程视频:https://www.bilibili.com/video/BV1z94y1C79p/?spm_id_from=333.337.search-card.all.click&vd_source=08f1bcaf25b9455e6a042db518c3b0db

简介

RC4是**对称密码(即加密和解密用的是同一个密钥)**算法中的流密码加密算法,密钥长度可变,面向字节操作

它以一个足够大的表S-box为基础,对表进行非线性变换(即函数f(x)的曲线在平面上不是直线,如指数、对数等),产生密钥流

明文+密钥=>密文 密文+密钥=>明文

加解密过程

加密过程

1、先初始化状态向量S(256个字节,用来作为密钥流生成的种子1)按照升序,给每个字节赋值0,1,2,3,4,5,6…,254,255
2、初始密钥(由用户输入),长度任意。如果输入长度小于256个字节,则进行轮转,直到填满。例如输入密钥的是1,2,3,4,5,那么填入的是1,2,3,4,5,1,2,3,4,5,1,2,3,4,5……由上述轮转过程得到256个字节的向量T(用来作为密钥流生成的种子2)
3、最后是根据向量S和T生成秘钥流与明文进行加密

代码通常的结构(以C语言为例)//1、初始化S表,K表    
for(i=0;i<256;i++){
     S[i]=i;
    T[i]=K[i % keylen];
}
//初始排列S
int j=0;
for(int i=0;i<256;i++){
    j=(j+S[i]+K[i])%256;
    swap(S[i],S[j]);//交换
}
//产生密钥流key[]
int i=0,j=0;
for(int r=0;r<strlen(M);i++){    //M是明文
    i=(i+1)%256;          //固定的
    j=(j+S[i])%256;       //固定的
    swap(S[i],S[j]);      //交换  
    t=(S[i]+S[j])%256;    //
    key[r]=S[t];            //生成密钥流
    M[r]^=key[r]            //解密明文 
}

解密过程

通过对加密过程的了解我们可以知道RC4的关键点在 密钥流的生成对明文的异或

所以在做题时我们应该找到:

1、填充K表的key

2、明文

所以:解密代码与加密代码雷同

特征识别

1、在加密过程中使用了==%256(取余)==

2、==交换(swap)==在加密过程中可以看到

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

魔改

1、可能会对S表修改,原来是0~255可以改为0 ~124等等

2、会对初始化S表增加可逆操作

for(i=0;i<256;i++)
{
    j=(j+s[i]+k[i])%256;
    temp=s[i];
    s[i]=s[j];
    s[j]=temp ^ 0x37;
}

3、在对明文异或时操作如

flag[k]=flag[k] ^ key[k] ^ 0x628;

注:具体查看具体分析,以上说的是本人遇到的一些魔改

源代码

由于 RC4 的加密和解密过程相同,因此可以使用同一个函数。

C语言

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void RC4_init(unsigned char *S, const unsigned char *key, int key_length) {
    int i, j = 0;
    unsigned char temp;

    // 初始化状态数组 S
    for (i = 0; i < 256; i++) {
        S[i] = i;
    }

    // 根据密钥打乱状态数组 S
    for (i = 0; i < 256; i++) {
        j = (j + S[i] + key[i % key_length]) % 256;
        // 交换 S[i] 和 S[j]
        temp = S[i];
        S[i] = S[j];
        S[j] = temp;
    }
}

void RC4_encrypt(const unsigned char *data, unsigned char *output, const unsigned char *key, int data_length, int key_length) {
    unsigned char S[256];
    int i, j = 0, k = 0;
    unsigned char temp;

    // 初始化状态数组 S
    RC4_init(S, key, key_length);

    // 加密过程
    for (i = 0; i < data_length; i++) {
        j = (j + 1) % 256;
        k = (k + S[j]) % 256;

        // 交换 S[j] 和 S[k]
        temp = S[j];
        S[j] = S[k];
        S[k] = temp;

        // 生成密钥流并加密数据
        output[i] = data[i] ^ S[(S[j] + S[k]) % 256];
    }
}

int main() {
    const char *key = "mysecretkey";              // 密钥
    const char *plaintext = "Hello, World!";      // 明文
    int key_length = strlen(key);
    int data_length = strlen(plaintext);
    unsigned char *ciphertext = (unsigned char *)malloc(data_length);
    unsigned char *decryptedtext = (unsigned char *)malloc(data_length);

    // 加密
    RC4_encrypt((unsigned char *)plaintext, ciphertext, (unsigned char *)key, data_length, key_length);
    printf("Ciphertext: ");
    for (int i = 0; i < data_length; i++) {
        printf("%02X ", ciphertext[i]); // 以十六进制输出密文
    }
    printf("\n");

    // 解密(使用相同的函数)
    RC4_encrypt(ciphertext, decryptedtext, (unsigned char *)key, data_length, key_length);
    printf("Decrypted text: %s\n", decryptedtext);

    // 释放内存
    free(ciphertext);
    free(decryptedtext);

    return 0;
}

python

def rc4(key, data):
    S = list(range(256))
    j = 0

    # 初始化状态数组 S
    for i in range(256):
        j = (j + S[i] + key[i % len(key)]) % 256
        S[i], S[j] = S[j], S[i]  # 交换 S[i] 和 S[j]

    i = j = 0
    output = []

    # 加密过程
    for byte in data:
        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]
        output.append(byte ^ K)  # 生成密钥流并加密数据

    return bytes(output)

# 示例使用
key = b'mysecretkey'  # 密钥
plaintext = b'Hello, World!'  # 明文

# 加密
ciphertext = rc4(key, plaintext)       #
print(ciphertext.hex().upper())  # 以十六进制输出密文

# 解密(使用相同的函数)
decryptedtext = rc4(key, ciphertext)    #
print(decryptedtext.decode())
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值