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 style="white-space:pre"> </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();
}

程序实现时,须要注意的是,状态向量数组S和暂时向量数组T的类型应设为unsigned char,而不是char。由于在一些机器下,将char默认做为signed char看待,在算法中计算下标i,j的时候,会涉及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&#15;&t餥6洲

密钥流:镈&#25;膺嚬3屽u

解密文件:我爱小兔子。

这是第一篇网络安全方面的博客。如有错误,欢迎指正!

RC4加密算法的原理及实现的更多相关文章

  1. RC4加密算法

    RC4是Ron Rivest在1987年设计的密钥长度可变的流加密算法.它加解密使用相同的密钥,因此也属于对称加密算法.RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一. ...

  2. php使用rc4加密算法

    /** * rc4加密算法,解密方法直接再一次加密就是解密 * @param  [type] $data 要加密的数据 * @param  [type] $pwd  加密使用的key * @retur ...

  3. 基于RC4加密算法的图像加密

    基于RC4加密算法的图像加密 某课程的一个大作业内容,对图像加密.项目地址:https://gitee.com/jerry323/RC4_picture 这里使用的是RC4(流.对称)加密算法,算法流 ...

  4. 信安实验-RC4加密算法

    RC4加密算法 算法具体就不介绍了,应信安老师要求整理及掌握. #include<bits/stdc++.h> using namespace std; const int N=256; ...

  5. AES 加密算法的原理详解

    AES 加密算法的原理详解 本教程摘选自 https://blog.csdn.net/qq_28205153/article/details/55798628 的原理部分. AES简介 高级加密标准( ...

  6. RC4 加密算法asp版

    Function RC4(data, Key) ), k(), outstr, Acii, j, tst, xre1, xre2, temp, x, t, y, qwe, zxc s(i) = i - ...

  7. java-信息安全(二)-对称加密算法DES,3DES,AES,Blowfish,RC2,RC4

    概述 信息安全基本概念: DES(Data Encryption Standard,数据加密标准) 3DES(Triple DES,三重数据加密算法(TDEA,Triple Data Encrypti ...

  8. C#加密解密(DES,AES,Base64,md5,SHA256,RSA,RC4)

    一:异或^简单加解密(数字类型) 1:原理: 异或用于比较两个二进制数的相应位,在执行按位"异或"运算时,如果两个二进制数的相应位都为1或者都为0,则返回0;如果两个二进制数的相应 ...

  9. nodejs中常用加密算法

    在常用的nodejs+express工程中,为了安全在登录及表单传输时,应该都需进行加密传输,目前个人常用到的加密方式有下列几种: 1.Hash算法加密: 创建一个nodejs文件hash.js,输入 ...

随机推荐

  1. AngulaJs -- 隔离作用域

    具有隔离作用域的指令最主要的使用场景是创建可复用的组件 创建具有隔离作用域的指令需要将scope属性设置为一个空对象{}.如果这样做了,指令的 模板就无法访问外部作用域了: <div ng-co ...

  2. IIS发布,无法显示CSS样式和图片

    描述: 最近给同事安装web程序时,把IIS安装好后,发布网站时,图片和css样式不显示. 程序没问题,发布也没问题. 后来网上一查,出错的原因可能是IIS的配置问题. 果然,按照网上的方法,顺利显示 ...

  3. VS 多工程代码编写

    VS工作目录,输出目录 C++项目,解决方案总文件夹下就只包含解决方案配置文件sln和一个项目总文件夹和一个Debug文件夹以及一个Release文件夹(共四个东东,其中Debug和Release文件 ...

  4. 2017/05/21 java 基础 随笔

    工具类:所有的方法都是静态的,如果一个类中所有的方法都是静态的,需要再多做一步,私有构造方法,不让其他类创建本类对象. 生成文档: java.lang 包不用导入 常见代码块的应用    * a:局部 ...

  5. RESET MASTER和RESET SLAVE使用场景和说明【转】

    [前言]在配置主从的时候经常会用到这两个语句,刚开始的时候还不清楚这两个语句的使用特性和使用场景. 经过测试整理了以下文档,希望能对大家有所帮助: [一]RESET MASTER参数 功能说明:删除所 ...

  6. 安装Scrapy遇到的坑

    安装过程怕是要吐血,架梯子等等结果被setuptools的版本给坑了. 参考网址: http://blog.csdn.net/YHYR_YCY/article/details/78876148 htt ...

  7. 初始ADO.NET数据操作

    以下介绍直接来源与百度百科,介绍十分全面和详细,作为小菜的我们没有理由不看完这些枯燥的介绍原有: ADO.NET的名称起源于ADO(ActiveX Data Objects),是一个COM组件库,用于 ...

  8. 虚拟机Failed to start LSB: Bring up/down networking

      1.执行 service network restart 出现以下错误 Restarting network (via systemctl):  Job for network.service f ...

  9. 字符串(string.cpp)

    字符串(string.cpp) 神TM字符串DP 题目描述: 小林和亮亮正在做一个游戏.小林随意的写出一个字符串,字符串仅由大写字母组成,然后指定一个非负整数m,亮亮可以进行至多m次操作.每次操作为交 ...

  10. maven正确的集成命令-U -B 等

    在持续集成服务器上使用怎样的 mvn 命令集成项目,这个问题乍一看答案很显然,不就是 mvn clean install 么?事实上比较好的集成命令会稍微复杂些,下面是一些总结: 不要忘了clean: ...