RC4加密解密算法123

2024-09-07 11:32
文章标签 算法 解密 加密 123 rc4

本文主要是介绍RC4加密解密算法123,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

       RC4是一种对称密码算法,它属于对称密码算法中的序列密码(streamcipher,也称为流密码),它是可变密钥长度,面向字节操作的流密码

RC4是流密码streamcipher中的一种,为序列密码。RC4加密算法是Ron Rivest在1987年设计出的密钥长度可变的加密算法簇。起初该算法是商业机密,直到1994年,它才公诸于众。由于RC4具有算法简单,运算速度快,软硬件实现都十分容易等优点,使其在一些协议和标准里得到了广泛应用。

流密码也属于对称密码,但与分组加密算法不同的是,流密码不对明文数据进行分组,而是用密钥生成与明文一样长短的密码流对明文进行加密,加解密使用相同的密钥

RC4算法特点:(1)、算法简洁易于软件实现,加密速度快,安全性比较高;(2)、密钥长度可变,一般用256个字节。

        对称密码算法的工作方式有四种:电子密码本(ECB, electronic codebook)方式、密码分组链接(CBC, cipherblock chaining)方式、密文反馈(CFB, cipher-feedback)方式、输出反馈(OFB, output-feedback)方式。

         RC4算法采用的是输出反馈工作方式,所以可以用一个短的密钥产生一个相对较长的密钥序列

         OFB方式的最大的优点是消息如果发生错误(这里指的是消息的某一位发生了改变,而不是消息的某一位丢失),错误不会传递到产生的密钥序列上;缺点是对插入攻击很敏感,并且对同步的要求比较高。

         RC4的执行速度相当快,它大约是分块密码算法DES的5倍,是3DES的15倍,且比高级加密算法AES也快很多。RC4算法简单,实现容易。RC4的安全保证主要在于输入密钥的产生途径,只要在这方面不出现漏洞,采用128bit的密钥是非常安全的。

         RC4算法加密流程:包括密钥调度算法KSA伪随机子密码生成算法PRGA两大部分(以密钥长度为256个字节为例)。

         密钥调度算法:首先初始化状态矢量S,矢量S中元素的值被按升序从0到255排列,即S[0]=00, S[1]=1, …, S[255]=255.同时建立一个临时矢量T,如果密钥K的长度为256字节,则将K赋给T。否则,若密钥长度为keylen字节,则将K的值赋给T的前keylen个元素,并循环重复用K的值赋给T剩下的元素,直到T的所有元素都被赋值。

      

在介绍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

for i=0 to 255 do

   j= ( j+S[i]+T[i])mod256;

   swap(S[i],S[j]);

3、产生密钥流

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-256vector<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]);}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&t餥6洲

密钥流:镈膺嚬3屽u

解密文件:我爱小兔子!


From:

http://blog.csdn.net/fengbingchun/article/details/42929883      这里面有调用OPENSSL中API的实例

http://www.tuicool.com/articles/AjAjm2

注:遇到RC4加密的数据 想解密数据 故此摘录


这篇关于RC4加密解密算法123的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1144937

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

poj 3974 and hdu 3068 最长回文串的O(n)解法(Manacher算法)

求一段字符串中的最长回文串。 因为数据量比较大,用原来的O(n^2)会爆。 小白上的O(n^2)解法代码:TLE啦~ #include<stdio.h>#include<string.h>const int Maxn = 1000000;char s[Maxn];int main(){char e[] = {"END"};while(scanf("%s", s) != EO

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

dp算法练习题【8】

不同二叉搜索树 96. 不同的二叉搜索树 给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。 示例 1: 输入:n = 3输出:5 示例 2: 输入:n = 1输出:1 class Solution {public int numTrees(int n) {int[] dp = new int

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

最大公因数:欧几里得算法

简述         求两个数字 m和n 的最大公因数,假设r是m%n的余数,只要n不等于0,就一直执行 m=n,n=r 举例 以18和12为例 m n r18 % 12 = 612 % 6 = 06 0所以最大公因数为:6 代码实现 #include<iostream>using namespace std;/