网络安全实验——RC4的实现
一、实验要求
① 编码实现RC4,简单分析代码
② 加解密个人信息,包含姓名学号,等相关信息
二、实验原理
RC4是RonRivest为RSA公司在1987年设计的一种流密码。它是一个可变密钥长度、面向字节操作的流密码。该算法以随机置换作为基础。分析显示该密码的周期很可能大于
1
0
100
10^{100}
10100。每输出1字节的结果仅需要8~16条机器操作指令,软件实现的该密码运行很快。RC4应用很广,例如,它用于作为EEE802.l1无线局域网标准一部分的WEP(WiredEquivalentPrivacy)协议和新的WiFi受保护访问协议(WPA)中。作为可选,它也被用于SecureShell(SSH)和Kerberos中。在当时RC4作为RSA公司的商业机密并没有公开。直到1994年9月,RC4算法才通过Cypherpunks匿名邮件列表匿名地公开于Internet上。
RC4算法非常简单,易于描述:用1~ 256个字节(82048位)的可变长度密钥初始化一个256个字节的状态向量S,S的元素记为S [0],S [1],…,S [255],从始至终置换后的S包含从0255所有的8位数。对于加密和解密,字节k是从S的255个元素中按一种系统化的方式选出的一个元素生成的。每生成一个k值,S中的元素个体就被重新置换一次。
初始化S
开始时,S中元素的值按升序被置为从0~255,即S[0],S[1],…,S[255]。同时建立一个临时向量T。如果密钥K的长度为256字节,则将K赋给T。否则若密钥长度为keylen个字节(keylen<256),则将K的值赋给T的前keylen个元素,并循环重复用K的值赋给T剩下的元素,直到T的所有元素都被赋值。这些预操作可被概括为如下:
/*初始化*/for i =0 to 255 do
S[i]= i
T[i]= K[i mod keylen]
然后用T产生S的初始置换,从S[0]到S[255],对每个S[i],根据由T[i]确定的方案,将S[i]可置换为S中的另一字节。
/*S的初始置换*/
j =0for i =0 to 255 do
j =(j + S[i]+ T[i])(mod 256)
swap(S[i], S[j])
因为对S的操作仅是交换,所以唯一的改变就是置换。S仍然包含所有值为0~255的元素。
密钥流的产生
向量S一旦完成初始化,输入密钥就不再被使用。密钥流的生成过程是,从S[0]到S[255],对每个S[i],根据S的当前配置,将S[i]与S中的另一字节置换。当S[255]完成置换后,操作继续重复从S[0]开始
/*密钥流的生成*/
i = j =0while(true)
i =(i +1)(mod 256)
j =(j + S[i])(mod 256)
swap(S[i],S[j])
t =(S[i]+ S[j])(mod 256)
k = S[t]
加密中,将k的值与明文的下一字节异或;解密中,将k的值与密文的下一字节异或。
三、代码说明
这里我使用java来实现RC4。
首先定义了几个变量
privateint[]S;//S盒privatechar[]K;//密钥privatechar[] data;//数据privatechar[] key_stream;//密钥流
初始化S
/**
* 初始化S
*/publicvoidinitS(){S=newint[256];int[]T=newint[256];//初始化for(int i =0; i <256; i++){S[i]= i;T[i]=K[i %K.length];}//S的初始置换int j =0;for(int i =0; i <256; i++){
j =(j +S[i]+T[i])%256;swap(S, i, j);}}
密钥流的产生
根据 S 盒生成与明文长度相同的秘钥流。
/**
* 产生密钥流
*/publicvoidgenerateKeyStream(){int i =0, j =0;for(int q =0; q < data.length; q++){
i =(i +1)%256;
j =(j +S[i])%256;swap(S, i, j);int t =(S[i]+S[j])%256;
key_stream[q]=(char)(S[t]);}}
加密与解密
由于异或运算的特性,使得加密与解密过程一致。如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文。调用过程如下:
/**
* 加密
* @param key 密钥
* @param plaintext 明文
* @return 密文
*/publicStringencrypt(String key,String plaintext){returnuseRC4(key, plaintext);}/**
* 解密
* @param key 密钥
* @param ciphertext 密文
* @return 明文
*/publicStringdecrypt(String key,String ciphertext){returnuseRC4(key, ciphertext);}/**
* 使用RC4
* @param key 密钥
* @param string 明文/密文
* @return 密文/明文
*/privateStringuseRC4(String key,String string){this.data = string.toCharArray();this.key_stream =newchar[data.length];this.K= key.toCharArray();//初始化SinitS();//产生密钥流generateKeyStream();StringBuffer result =newStringBuffer();//逐字加密数据for(int i =0; i < data.length; i++){
result.append((char)(string.charAt(i)^ key_stream[i]));}//输出结果return result.toString();}
四、实验结果
测试数据如下(考虑隐私,已经去掉了学号等信息):
我把我的整个灵魂都给你,连同它的怪癖,耍小脾气,忽明忽暗,一千八百种坏毛病。它真讨厌,只有一点好,爱你。——from 王小波
测试代码如下
String key ="love";String plaintext =readFile("src/input.txt");RC4 test =newRC4();System.out.println("明文为:");System.out.println(plaintext);System.out.println("使用RC4加密后的密文:");String ciphertext = test.encrypt(key, plaintext);System.out.println(ciphertext);System.out.println("使用RC4解密该密文得到:");String plaintext_rc4 = test.decrypt(key, ciphertext);System.out.println(plaintext_rc4);
实验结果如下:
明文为:
我把我的整个灵魂都给你,连同它的怪癖,耍小脾气,忽明忽暗,一千八百种坏毛病。它真讨厌,只有一点好,爱你。——from 王小波
使用RC4加密后的密文:
轁亰2:V覃嬽丯邎妢孋〾戡扎拡癖敔丹炏鮭達绫佹¥輳咲家瘸悁癓;聂岇脐氖ᄋ彳曚忩昲₩乶印冺瘾禟圴殃畱ク密睾诣危厯枒仦炁妫"牪佽ぷ―‚§.-3Y珧屯汞
使用RC4解密该密文得到:
我把我的整个灵魂都给你,连同它的怪癖,耍小脾气,忽明忽暗,一千八百种坏毛病。它真讨厌,只有一点好,爱你。——from 王小波
综上,该实验能成功实现简单的RC4加密解密。
版权归原作者 雨落俊泉 所有, 如有侵权,请联系我们删除。