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. 20155321 2016-2017-2 《Java程序设计》第五周学习总结

    20155321 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 第八章 异常处理 Java提供特有的语句进行处理 try { 需要被检测的代码; } cat ...

  2. Android手机间无线互传功能探索及实现

    年前研究了一下Android如何实现无线互传的功能,写了个小demo,最近无事,遂整理一下,与各位共享.前期调研发现,Android想要实现无线互传有以下几种技术:1,Bluetooth通行已久,简单 ...

  3. binlog2sql的安装及使用

    binlog2sql是大众点评开源的一款用于解析binlog的工具,在测试环境试用了下,还不错. DBA或开发人员,有时会误删或者误更新数据,如果是线上环境并且影响较大,就需要能快速回滚.传统恢复方法 ...

  4. Python常用time处理

    #coding=utf-8 # python2.7工具语句 from sys import version_info import time import datetime if version_in ...

  5. ASP.NET中Request.ApplicationPath、Request.FilePath、Request.Path、.Request.MapPath、

    1.Request.ApplicationPath->当前应用的目录    Jsp中, ApplicationPath指的是当前的application(应用程序)的目录,ASP.NET中也是这 ...

  6. mybatis,genarate自动生成代码

    ---恢复内容开始--- generatorConfig.xml配置文件: <?xml version="1.0" encoding="UTF-8"?&g ...

  7. wpf DataTemplate ColumnDefinition width equal

    <Grid.ColumnDefinitions> <ColumnDefinition SharedSizeGroup="col1" /> <Colum ...

  8. JS模块化编程(二):require.js基本用法

    require.config() 接受一个配置对象 常用属性: paths: shim: 配置不兼容的模块 baseUrl: 引用模块的文件基目录

  9. python的map,filter,reduce学习

    python2,python3中map,filter,reduce区别: 1,在python2 中,map,filter,reduce函数是直接输出结果. 2,在python3中做了些修改,输出前需要 ...

  10. python的mock功能,感觉入门了~~~

    主要实现语法有patch, patch.object, Mock(). 下面的测试太赤裸裸了,只是为了熟悉语法. import unittest from unittest.mock import p ...