博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RC4加密算法的原理及实现
阅读量:6972 次
发布时间:2019-06-27

本文共 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如需转载请自行联系原作者 

你可能感兴趣的文章
mysql 控制台上传数据库
查看>>
洛谷P1196 银河英雄传说
查看>>
aop为系统添加操作日志,注入或配置声明的方式来实现
查看>>
好用的日期控件jeDate
查看>>
Ajax学习之------>Ajax和Json实现无限下拉框联动(上)
查看>>
古今之成大事业、大学问者,必经过三种之境界
查看>>
我的Android进阶之旅------>Android中编解码学习笔记
查看>>
我的Android进阶之旅------>android如何将List请求参数列表转换为json格式
查看>>
转载:负载均衡器技术Nginx和F5的优缺点对比
查看>>
【资源共享】5G AP分析
查看>>
APP测试与Web测试的区别
查看>>
模式识别,计算机视觉领域,期刊
查看>>
AngularJs的UI组件ui-Bootstrap分享(三)——Accordion
查看>>
中缀、前缀和后缀表达式
查看>>
Redis 自定义对象 cannot be cast to java.lang.String
查看>>
[题解]第十一届北航程序设计竞赛预赛——H.高中数学题
查看>>
内置对象Array及Array常见操作
查看>>
oracle 表字段新增、修改、删除、重命名以及表重命名
查看>>
Python连接MySQL之Python库pymysql
查看>>
Android 图文教学让你彻底理解activity启动模式
查看>>