RC4加密算法的原理及实现

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<kl;++i){ //随机生产长度为keylen字节的密钥 int tmp=rand()%256; K.push_back(char(tmp)); } } /* 由明文产生密文 */ void encryption(const string &,const string &,const string &); private: unsigned char S[256]; //状态向量共256字节 unsigned char T[256]; //暂时向量共256字节 int keylen; //密钥长度keylen个字节取值范围为1-256 vector<char> K; //可变长度密钥 vector<char> 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="<<j<<endl; S[i]=S[i]+S[j]; S[j]=S[i]-S[j]; S[i]=S[i]-S[j]; } } /* 生成密钥流 len:明文为len个字节 */ void keyStream(int len); }; void RC4::keyStream(int len) { initial(); rangeS(); int i=0,j=0,t; while(len--){ i=(i+1)%256; j=(j+S[i])%256; S[i]=S[i]+S[j]; S[j]=S[i]-S[j]; S[i]=S[i]-S[j]; t=(S[i]+S[j])%256; k.push_back(S[t]); } } void RC4::encryption(const string &plaintext,const string &ks,const string &ciphertext) { ifstream in; ofstream out,outks; in.open(plaintext); //获取输入流的长度 in.seekg(0,ios::end); int lenFile=in.tellg(); in.seekg(0, ios::beg); //生产密钥流 keyStream(lenFile); outks.open(ks); for(int i=0;i<lenFile;++i){ outks<<(k[i]); } outks.close(); //明文内容读入bits中 unsigned char *bits=new unsigned char[lenFile]; in.read((char *)bits,lenFile); in.close(); out.open(ciphertext); //将明文按字节依次与密钥流异或后输出到密文文件里 for(int i=0;i<lenFile;++i){ out<<(unsigned char)(bits[i]^k[i]); } <span> </span>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<lenFile;++i) out<<(unsigned char)(bitKey[i]^bitCip[i]); out.close(); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/d0e5c71977a30feaf68425e6b2fadd8c.html