本文共 2918 字,大约阅读时间需要 9 分钟。
RC4于1987年提出和DES算法一样。是一种对称加密算法也就是说使用的密钥为单钥或称为私钥。
但不同于DES的是。RC4不是对明文进行分组处理而是字节流的方式依次加密明文中的每个字节。解密的时候也是依次对密文中的每个字节进行解密。
RC4算法的特点是算法简单执行速度快。并且密钥长度是可变的可变范围为1-256字节(8-2048比特)在现在技术支持的前提下当密钥长度为128比特时用暴力法搜索密钥已经不太可行所以能够预见RC4的密钥范围任然能够在今后相当长的时间里抵御暴力搜索密钥的攻击。实际上现在也没有找到对于128bit密钥长度的RC4加密算法的有效攻击方法。
在介绍RC4算法原理之前。先看看算法中的几个关键变量
1、密钥流RC4算法的关键是依据明文和密钥生成相应的密钥流密钥流的长度和明文的长度是相应的。也就是说明文的长度是500字节那么密钥流也是500字节。当然加密生成的密文也是500字节。由于密文第i字节=明文第i字节^密钥流第i字节
2、状态向量S长度为256。S[0],S[1].....S[255]。每一个单元都是一个字节。算法执行的不论什么时候。S都包含0-255的8比特数的排列组合仅仅只是值的位置发生了变换
3、暂时向量T长度也为256每一个单元也是一个字节。
假设密钥的长度是256字节。就直接把密钥的值赋给T否则轮转地将密钥的每一个字节赋给T。
4、密钥K长度为1-256字节。注意密钥的长度keylen与明文长度、密钥流的长度没有必定关系。通常密钥的长度趣味16字节128比特。
RC4的原理分为三步
1、初始化S和T
for i=0 to 255 do
S[i]=i;
T[i]=K[ imodkeylen ];
2、初始排列S
j=0;
for i=0 to 255 do
j= ( j+S[i]+T[i])mod256;
swap(S[i],S[j]);
3、产生密钥流
i,j=0;
for r=0 to len do //r为明文长度r字节
i=(i+1) mod 256;
j=(j+S[i])mod 256;
swap(S[i],S[j]);
t=(S[i]+S[j])mod 256;
k[r]=S[t];
以下给出RC4加密解密的C++实现
加密类
/* 加密类*/class RC4 {public: /* 构造函数。參数为密钥长度 */ RC4(int kl):keylen(kl) { srand((unsigned)time(NULL)); for(int i=0;i解密类K; //可变长度密钥 vector k; //密钥流 /* 初始化状态向量S和暂时向量T供keyStream方法调用 */ void initial() { for(int i=0;i<256;++i){ S[i]=i; T[i]=K[i%keylen]; } } /* 初始排列状态向量S。供keyStream方法调用 */ void rangeS() { int j=0; for(int i=0;i<256;++i){ j=(j+S[i]+T[i])%256; //cout<<"j="< < out.close(); delete []bits;}
/* 解密类*/class RC4_decryption{public: /* 构造函数。參数为密钥流文件和密文文件 */ RC4_decryption(const string ks,const string ct):keystream(ks),ciphertext(ct) {} /* 解密方法參数为解密文件名称 */ void decryption(const string &);private: string ciphertext,keystream;};void RC4_decryption::decryption(const string &res){ ifstream inks,incp; ofstream out; inks.open(keystream); incp.open(ciphertext); //计算密文长度 inks.seekg(0,ios::end); const int lenFile=inks.tellg(); inks.seekg(0, ios::beg); //读入密钥流 unsigned char *bitKey=new unsigned char[lenFile]; inks.read((char *)bitKey,lenFile); inks.close(); //读入密文 unsigned char *bitCip=new unsigned char[lenFile]; incp.read((char *)bitCip,lenFile); incp.close(); //解密后结果输出到解密文件 out.open(res); for(int i=0;i
程序实现时须要注意的是状态向量数组S和暂时向量数组T的类型应设为unsigned char而不是char。由于在一些机器下将char默认做为signed char看待在算法中计算下标ij的时候会涉及char转int。假设是signed的char。那么将char的8位复制到int的低8位后还会依据char的符号为在int的高位补0或1。由于密钥是随机产生的假设遇到密钥的某个字节的高位为1的话那么计算得到的数组下标为负数就会越界。
程序执行演示样例
main函数
int main(){ RC4 rc4(16); //密钥长16字节 rc4.encryption("明文.txt","密钥流.txt","密文.txt"); RC4_decryption decrypt("密钥流.txt","密文.txt"); decrypt.decryption("解密文件.txt");}
明文我爱小兔子
密文'柀L&t餥6洲
密钥流镈膺嚬3屽u
解密文件我爱小兔子。
这是第一篇网络安全方面的博客。如有错误欢迎指正
本文转自mfrbuaa博客园博客原文链接http://www.cnblogs.com/mfrbuaa/p/5405809.html如需转载请自行联系原作者