一.实验目的
熟悉流密码RC4算法。在此基础上,通过运用高级程序设计语言,设计并实现
RC4算法。
- 写出RC4加密工具的设计思路
- 重要代码的注释
二.实验原理
RC4算法由RSA三人组成员之一的R. Rivest 在1987年开发,是目前世界上普遍使用的流密码算法之一,不仅应用于Microsoft Windows, Lous Notes等应用软件中,还应用于安全套接层(Secure Sockets Layer, SSL) /传输层安全协议(TLS) 保护Internet上的业务流。RC4是一个可变密钥长度的流密码,它以一个数据表s为基础,对s进行非线性变换,产生非线性的密钥流序列。数据表S的长度可为任意值,但一般为 256个字节。密钥流序列的生成包括两个过程:密钥安排算法(Key Scheduling Algorithm, KSA) 和伪随机子密钥序列生成算法(Pseudo-Random Generation Algorithm, PRGA)。
(1)密钥安排算法
密钥安排算法又称为RC4的初始化算法。以数据表S的长度为256个字节为例,并且将输入的种子密钥标记为Key, Key的长度记为keylen.首先将S中的元素按升序进行线性填充,即S[0]=0, S[1]=1,…,S[255]=255。建立一个临时数组T256],将Key赋给T。如果Key的长度小于T,则依次重复用Key的值填充T中的元素,直到T的所有元素都被赋值。然后用T产生S的初始置换,即对每个S[i](i为0~255),计算j=(j+ S[i]+ T[i])mod256,然后交换S[q]和S[j].需要明确的是,因为对数据表s的操作仅是置换,s仍然包含所有0-255的元素。
(2)伪随机子密钥序列生成算法
数据表S的初始化且完成,种子密钥Key就不再被使用。伪随机子密钥序列SubKey的生成是从i=0,j=0开始,依据以下步骤计算:
①i=(i+ 1) mod 256。
②j=(j+ S[i]) mod 256。
③交换S[i]和S[j]。
④t= (S[I) + S[j]mod 256。
⑤S[4]为本次子密钥。
如果明文plaintext的长度超过256个字节,则s中的256个字节完成轮置换后,
操作将继续重复,直到对明文最后一个字符加密/解密的子密钥生成为止。
三.实验步骤
[例]假设RC4的数据表s的长度为8个字节,说明RC4的密钥安排和伪随机子密钥序列的生成步骤:
第1步:初始化数据表S的各个元素为S[0]=O.S[1]=1,S[2]=2,S[3]=3.S[4]=4.S[5]=5,S[6]=6,S[7]=7。
int main() {
cout << "请输入数据表s的长度:" << endl;
cin >> n;
cout << "初始化s为:" << endl;
for (int i = 0; i < n; i ++){
s[i] = i;
cout << s[i];
}
【代码运行部分截图】
第2步:选取一个密钥,它的每个元素是0~7中的任意一个数,例如选择Key[O]=5
Key[1]=6, Key[2]=7。填充数组T[8].得到T0]=5,T[1]=6,T[2]=7,T[3]=5,T[4]=6,T[5]=
7,T[6]=5,T[7]=6。
cout << endl << "初始化t为:" << endl;
for (int i = 0; i < n; i++) {
int k[] = {5, 6, 7};
int m = i % length(k);
t[i] = k[m];
cout << t[i];
}
【代码运行部分截图】
第3步:从i=0和j=0开始,循环8次更新数据表S。例如,第一次计算j=(j+S[i]+S[j]mod8,即j=(0+0+5)mod8=5。交换S[0]和S[5],得到新的数据表S为S[0]=5,S[1]=1, S[2]=2, S[3]=3, S[4]=4, S[5]=0, S[6]=6, S[7]=7。循环结束后,数据表S更新为S[0]=5,S[1]=4,S[2]=0,S[3]=2,S[4]=1,S[5]=6,S[6]=3,S[7]=2。
cout << endl << "循环更新后的s为:" << endl;
int j = 0;
for (int i = 0; i < n; i ++) {
j = (j + s[i] + t[i]) % n;
swap(s[i], s[j]);
cout << s[i];
}
【代码运行部分截图】
第4步:从i=0和j= 0开始,使用数据表s生成伪随机子密钥序列。例如,第一个子密钥SubKey[0]的计算如下:i=(i+1)mod8=(0+1)mod8=1,j=(j+ S[i])mod8=(0+S[1])
mod8=(0+4)mod8=4。交换S[i]和S[j],即交换S[1]和S[4]t=(S[i])+S[j])mod8=(S[1]+S[4])mod8=(1+4)mod8=5,SubKey[0]=S[t]=S[5]=6。重复进行该过程,直到生成的二进制位数等于明文的二进制位数。
cout << endl << "生成的密钥流为:" << endl;
int x = 0;
int y = 0;
int tt;
int key[10010];
for (int k = 0; k < n; k ++){
// cout << endl << "生成的密钥流的其中一个字节为:" << endl;
x = (x + 1) % n;
y = (y + s[x]) % n;
swap(s[x], s[y]);
tt = (s[x] + s[y]) % n;
key[k] = s[tt];
cout << key[k];
// cout << "加密中,将" << key << "与下一明文字节异或"<<endl;
// break;
}
【代码运行部分截图】
【完整代码】