RC4实验报告

RC4实验

一、实验背景

1. 对称加密算法

​ 对称加密,也叫私钥加密,指的是加密密钥和解密密钥相同的密码算法。它要求发送方和接收方在进行加密通信之前共同商定一个密钥,算法的安全性也依赖于这个密钥,泄露密钥就意味着任何人都可以对加密的消息进行解密,所以保管密钥对于对称加密算法的通信十分关键。相比于公钥加密算法,对称加密算法具有计算量小、加密速度快、加密效率高等优点,但也存在多人通信时密钥数量太多所导致的密钥分发和管理难度大的缺点使得其使用成本较高,而且对称密钥无法提供签名功能。常用的对称加密算法有:DES,RC4,IDEA算法等。

2.流密码

​ 流密码,又叫序列密码,是对称加密算法的一种,加密和解密双方使用相同的伪随机加密数据流(pseudo-randomstream)作为密钥,明文数据每次与密钥数据流顺次对应加密,得到密文数据流。这种密码体制只有混淆而没有扩散,与分组密码的最主要区别就是有记忆。流密码根据加密器中的记忆原件的状态$\sigma_i$是否依赖于输入的明文字符,可进一步分为同步和自同步两种。

​ 流密码最初主要用于政府、军方等重要部门,因此不像分组密码一样有公开的国际标准,大多的设计和成果都是保密的。但随着其需求的增大,更多公开的流密码技术也渐渐出现,如FISH,Helix,RC4,A5等。

3. RC4加密算法

​ RC4(Rivest Cipher 4),是一种密钥长度可变的流加密算法。其原理主要包括了初始化算法(KSA):基于输入对称密钥K,置换状态数组;和伪随机子密码生成算法(PRNG):扩充状态数组,加密明文数据两个部分。初始化的作用是将S盒打乱,确保每个元素都会被随机处理。而伪随机子密码生成算法则是产生伪随机流,与明文进行异或后产生密文。由于使用异或运算进行加密,RC4算法存在密钥序列重复从而导致的被破解的风险,在2015年,比利时鲁汶大学的研究人员也在75小时内获得了有RC4加密的明文。

二、实现原理

1. KSA算法

​ KSA算法的目标是基于输入的密钥K产生状态数组的一个置换,主要步骤为先初始化一个单位数组S,再根据密码的位数对S进行基于密钥K的置换得到本次加密的状态数组。以下为具体代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int *S RC4_KSA(int K[])
{
//RC4 KSA
int S[256]={0};
for(int i=0;i<255;i++)
{
S[i]=i; //初始化单位数组
}
int j=0, temp;
for(int i=0;i<255;i++) //256轮置换
{
j=(j+s[i]+K[i%(length(K))])% 256;
temp=S[i];
S[i]=S[j];
S[j]=temp;
}
return S;
}

2. PRNG算法

​ 此算法的目的是使用上一步的置换数组来产生伪随机序列,与明文异或产生密文。原理和代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
int *C RC4(int S[], int M[]) //输入S和明文数组
{
int i=0, j=0,temp T[256]={0};
for(int k=0;k<(length(M)))
{
i=(i+1) % 256;
j=(j+S[i]) % 256;
temp=S[i]; S[i]=S[j]; S[j]=temp;
T[k] = S[(S[i]+S[j]) % 256];//产生伪随机序列
C[k] = T[k] ^ M[k];//明文与伪随机序列异或产生密文
}
return C;
}

三、验证和测试

1. 使用openssl进行测试

经查阅文档,在openssl中使用RC4的相关函数为:

1
2
3
4
5
6
#include <openssl/rc4.h>

void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data);

void RC4(RC4_KEY *key, unsigned long len, const unsigned char *indata,
unsigned char *outdata);

使用Linux下C++编程的完整程序为:

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
#include<iostream>
#include<string>
#include<stdio.h>
#include<openssl/rc4.h>//添加RC4的库

using namespace std;

int main()
{
RC4_KEY rc4_key; //生成密钥
string p = "This is the plain text."; //设置明文
string key = "12345ABCDE";
unsigned char * cipherText = new unsigned char [p.length()];
unsigned char * plainText = (unsigned char *)p.c_str();

cout<<"初始明文为:";
for(int i = 0;i<p.length();i++)
{
printf("%0x",plainText[i]);
}
cout<<endl;

RC4_set_key(&rc4_key, key.length(), plainText);//设置密钥
RC4(&rc4_key, p.length(), plainText, cipherText);//进行加密

string cipher = (char *)cipherText;
cout<<"密文为:";
for(int i = 0;i<p.length();i++)
{
printf("%0x",cipherText[i]);
}
cout<<endl;

RC4_set_key(&rc4_key, key.length(), plainText);//再次设置密钥(不设置无法解密)
RC4(&rc4_key, p.length(), cipherText, plainText);//使用相同密钥解密,获得明文
cout<<"解密后得到的明文为:";
for(int i = 0;i<p.length();i++)
{
printf("%0x",plainText[i]);
}
cout<<endl;

}

可见,当前程序的确可以使用openssl中的RC4相关函数进行可逆的加解密运算,也就证明了算法的正确性。

2. 时间开销

openssl中自带了可以测试各种算法性能的函数speed指令,本次将RC4与DES,RSA相比,观察其时间开销和性能。

在Linux命令行输入openssl进入其命令界面后,分别输入:

1
2
3
speed rc4
speed des
speed rsa

结果分别为:

fig-1

fig-2

fig-3

​ 综合上面三张图,不难看出,在明文大小相同的情况下RC4的运算速度最快,DES次之,RSA最慢,这也很好地符合了我们的预期。就拿1024bit数据加密来说,RC4在3秒内可以进行超过百万次加密,DES在cbc模式下为3秒进行近二十万次加密,而RSA在10秒内只能进行8万余次的私钥计算和13万余次的公钥加密计算。从这里我们也可以看出RC4在加密效率上有着很高的优越性。

四、实验结论

​ 本次实验,通过深入了解RC4算法的起源,发展和特点,我更加透彻地了解了流密码的算法原理,安全性等。而通过亲自编写程序简易地实现该算法也让我能体会到流密码与分组密码、公钥密码的不同之处。总的来说,RC4是一种安全性很高,密钥长度非常灵活的加密算法,值得我们进行深入的学习。


RC4实验报告
https://adamyoung71.github.io/2019/08/14/2019-8-14-RC4实验/
作者
Adam
发布于
2019年8月14日
许可协议