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. AngularJs -- 指令中使用子作用域

    下面将要介绍的指令会以父级作用域为原型生成子作用域.这种继承的机制可以创建一个隔离层,用来将需要协同工作的方法和数据模型对象放置在一起. ng-app和ng-controller是特殊的指令,因为它们 ...

  2. TED_Topic10:The case for engineering our food

    By Pamela Ronald Pamela Ronald studies the genes that make plants more resistant to disease and stre ...

  3. grep和sed匹配多个字符关键字的用法

    GNU sed和UNIX sed 写法不一样 匹配多个关键词,打印出匹配的行,效果类似于 grep grep hello\|world file > output 或者用扩展正则 grep -E ...

  4. pymongo创建索引

    from database import db db_list = ["table1", "table2", "table3", " ...

  5. 008_MAC 终端使用技巧

    一.常用终端命令. <1>reset 的作用很简单——将目前「终端」屏幕上的内容清空,就好像刚刚打开终端一样. <2>如果你在一条终端命令中发现有输入错误的话,那么用 cont ...

  6. day22-23作业

    1.字节流  字符流    2.read()  3.-1  4.System.out  5.InputStream  6.OutputStream 1.IO流按流向分为输入流和输出流,即输入流和输出流 ...

  7. 001_Eclipse编写第一个Java程序

    1 下载并安装jdk 2 下载较新版本的eclipse,eclipse都是非安装版的,解压缩即可. 3 双击eclipse.exe,打开elipse软件 4 FileàNewàProject 5 选择 ...

  8. jenkins 2:用ssh agent插件在pipeline里实现scp和远程执行命令

    昨晚测试成功了. 现在ssh agent的认证,已不支持明文用户密码,而只能用加密方式实现. 所以我先在jenknis和nginx服务器之后,实现ssh免密码rsa证书登陆. 私钥放jenkins,公 ...

  9. 【PAT】1020 Tree Traversals (25)(25 分)

    1020 Tree Traversals (25)(25 分) Suppose that all the keys in a binary tree are distinct positive int ...

  10. Linux命令执行顺序— ||和&&和; 比较

    Linux命令执行顺序— ||和&&和; command1 && command2: &&左边的command1执行成功(返回0表示成功)后,& ...