RC4加密算法

RC4

Posted by MetaNetworks on May 20, 2020
本页面总访问量

RC4运行过程

步骤

RC4为一种流密码加密机制,遵循一次一密。

  • 初始化$S$向量
  • 根据输入的密钥初始化$T$向量
  • 用$T$向量打乱$S$向量,得到向量$S’$
  • 传入待加密的文本TEXT,按照字节,分别与$S`$表中的某一值进行异或。可以得到加密后的文本以及与待加密文本异或的字节串
  • 若要解密,则将加密后的文本与字节串进行异或即可

RC4C++实现:

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <iostream>

class RC4 {
public:
    static const int s_size = 256;

    RC4(std::string &key) {
        inputKey = key;
        init();
    }

    /// 加密text,引用text直接被加密,返回的std::string为密钥流
    std::string encryption(std::string &text);

    /// 解密text,引用encrypted_text直接被解密,返回的为状态码
    int decryption(std::string &encrypted_text, std::string &key);

private:
    void init();

    void _init_t(); //初始化

    void _init_s();

    int swap(int l_index, int r_index); // 交换s盒

    void transform();

    std::string inputKey;
    char s[s_size]{}; //S盒子
    const char *t{}; //临时向量T
    char k; //当前生成的k
};

void RC4::_init_s() {
    for (int i = 0; i < RC4::s_size; ++i) {
        s[i] = char(i);
    }
}

void RC4::_init_t() {
    auto length = inputKey.length();
    if (length == s_size) {
        //则将K赋给T
        t = inputKey.c_str();
    } else if (length > s_size) {
        inputKey = inputKey.substr(0, s_size);
        t = inputKey.c_str();
    } else {
        auto tmp = (char *) malloc(sizeof(char) * s_size);
        for (int i = 0; i < s_size; ++i) {
            tmp[i] = inputKey[i % s_size];
        }
        t = tmp;
    }
}

void RC4::init() {
    _init_s();
    _init_t();
    transform();
}

/// 使用T向量打乱S向量
void RC4::transform() {
    int j = 0;
    for (int i = 0; i < s_size; ++i) {
        j = (j + s[i] + t[i]) % s_size;
        swap(i, j);
    }
}

int RC4::swap(int l, int r) {
    if (l >= 0 && r >= 0 && l < s_size && r < s_size && l != r) {
        char tmp = s[l];
        s[l] = s[r];
        s[r] = tmp;
    }
    return 0;
}

/// 生成密钥流,text直接被加密,return密钥流
std::string RC4::encryption(std::string &text) {
    std::string key;
    auto length = text.length();
    int i = 0, j = 0, index = 0;
    int en_index = 0;
    while (--length) {
        i = (i + 1) % s_size;
        j = (j + s[i]) % s_size;
        swap(i, j);
        index = (s[i] + s[j]) % s_size;
        k = s[index];
        text[en_index] ^= k;
        key += k;
        en_index += 1;
    }
    return key;
}

int RC4::decryption(std::string &encrypted_text, std::string &key) {
    auto length = encrypted_text.length();
    int en_index = 0;
    while (--length) {
        encrypted_text[en_index] ^= key[en_index];
        en_index += 1;
    }
    return 0;
}


int main(int argc, char *argv[]) {
    std::string inputKey = "n92tU+3m52wcyRBjvpJygCM9G53nETMzaSMALMyzxFo=";
    RC4 rc4(inputKey);
    std::string text = "hello";
    std::cout << "origin: " << text << std::endl;
    std::string key = rc4.encryption(text);
    std::cout << "encrypted: " << text << std::endl;
    rc4.decryption(text, key);
    std::cout << "decrypted: " << text << std::endl;
    return 0;
}

执行结果

1
2
3
origin: hello
encrypted: �e?lo
decrypted: hello