简述

RC4 是一个典型的基于非线性数组变换的序列密码。以一个足够大的数组为基础,对其进行非线性变换,产生密钥序列,一般把这个大数组称为 S 盒。

RC4 包含两个处理过程:密钥调度算法(KSA,Key-Scheduling Algorithm),用来置乱 S 盒的初始排列,伪随机生成算法(PRGA,Pseudo Random-Generation Algorithm),用来输出随机序列并修改 S 的当前按排列顺序。

这个代码参考《密码学》课本上讲解的原理就能写出来, 百度百科 上也参考代码xd

加密 / 解密

  • 加密时,将密钥流逐字节与明文字节异或
  • 解密时,将密钥流逐字节与密文字节异或

异或操作

以下三个数,知道两个就能获得另一个

1
2
3
a^b=c
c^b=a
a^c=b

实验代码

rc4.cpp

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
#include <bitset>
#include <iostream>
using namespace std;

int main()
{
string msg = "你好jck"; //明文
string key = "jckjsdfsgck"; //密钥

int s_length = msg.length(); //明文长度
int k_length = key.length(); // 密钥长度
int n = 256; //S盒大小

int i, j;

char *S = new char[n];
char *T = new char[n];
char *K = new char[k_length]; //存密钥,也可省去
char *C = new char[s_length+1]; //存明文,最后一位'\0'
for (i = 0; i < s_length; i++) {
C[i] = msg[i];
}

// 1.初始化转换表,填充S数组
for (i = 0; i < k_length; i++) {
K[i] = key[i];
}
for (i = 0; i < n; i++) {
S[i] = i;
T[i] = K[i%k_length];
}

// 2.密钥调度算法KSA,置换
char temp;
for (i = 0, j = 0; i < n; i++) {
j = (j + S[i] + T[i]) % n;
temp = S[i];
S[i] = S[j];
S[j] = temp;
}

// 3.伪随机生成算法PRGA
int t, c;
char* keystream = new char[s_length]; //密钥流
i = j = 0;
for (c = 0; c < s_length; c++) {
i = (i + 1) % n;
j = (j + S[i]) % n;
temp = S[i];
S[i] = S[j];
S[j] = temp;
t = (S[i] + S[j]) % n;
keystream[c] = S[t];
}

// 4.加密,明文与密钥流异或
for (i = 0; i < s_length; i++)
C[i] ^= keystream[i];
C[i] = '\0';
cout << "密文:" << C << endl;

// 5.解密,密文与密钥流异或
for (i = 0; i < s_length; i++)
C[i] ^= keystream[i];
C[i] = '\0';
cout << "明文:" << C << endl;

return 0;
}

结语

简单实现了一种流密码,实验性代码显然不能用到实际环境,了解原理倒是可以上手敲代码,实际还是推荐使用封装好的函数。