RC4加解密算法
RC简介
在
特点
RC4由伪随机数生成器和异或运算组成。RC4的密钥长度可变,范围是[1,255]。RC4一个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钥并产生一个S盒。S盒用来加密数据,而且在加密过程中S盒会变化。''
由于异或运算的对合性,RC4加密解密使用同一套算法。
相关变量解释
-
S-Box 也就是所谓的S盒,是一个256长度的char型数组,每个单元都是一个字节,算法运行的任何时候,S都包括0-255的8比特数的排列组合,只不过值的位置发生了变换。
-
密钥K char key[256] 密钥的长度keylen与明文长度、密钥流的长度没有必然关系
-
临时向量k 长度也为256,每个单元也是一个字节。如果密钥的长度是256字节,就直接把密钥的值赋给k,否则,轮转地将密钥的每个字节赋给k
流程
1.rc4_init 初始化S盒
包含三个参数
参数1是一个256长度的char型数组,定义为: unsigned char sBox[256];
参数2是密钥,其内容可以随便定义:char key[256];
参数3是密钥的长度,Len = strlen(key);
初始化长度为256的S盒。第一个for循环将0到255的互不重复的元素装入S盒。第二个for循环根据密钥打乱S盒。
i确保S-box的每个元素都得到处理,j保证S-box的搅乱是随机的。
void rc4_init(unsigned char *s,unsigned char *key, unsigned long Len) { //初始化长度为256的S盒 int i=0,j=0; char k[256]={0}; unsigned char tmp=0; for(i=0;i<256;i++) { s[i]=i;//将0到255的互不重复的元素装入S盒 k[i]=key[i%Len]; } for(i=0;i<256;i++) { //第二个for循环根据密钥打乱S盒 //i确保S-box的每个元素都得到处理,j保证S-box的搅乱是随机的 j=(j+s[i]+k[i])%256; tmp=s[i]; s[i]=s[j]; //交换s[i]和s[j] s[j]=tmp; } }
2.rc4_crypt 加解密(通过得到的S盒进行加密解密)
包含三个参数
参数1是上边rc4_init函数中,被搅乱的S-box;
参数2是需要加密的数据data;
参数3是data的长度.
每收到一个字节,就进行while循环。通过一定的算法定位S盒中的一个元素,并与输入字节异或,得到k。循环中还改变了S盒。如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文。
void rc4_crypt(unsigned char *s,unsigned char *Data,unsigned long Len) { int i=0,j=0,t=0; unsigned long k=0; unsigned char tmp; for(k=0;k<Len;k++)//循环中还改变了S盒 { i=(i+1)%256; j=(j+s[i])%256; tmp=s[i]; s[i]=s[j]; //交换s[x]和s[y] s[j]=tmp; t=(s[i]+s[j])%256; //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //每收到一个字节,就进行while循环。通过一定的算法定位S盒中的一个元素 Data[k]^=s[t];//并与输入字节异或,得到k } //如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文 }
3.整体算法代码
#include<bits/stdc++.h> using namespace std; void rc4_init(unsigned char *s,unsigned char *key, unsigned long Len) { //初始化长度为256的S盒 int i=0,j=0; char k[256]={0}; unsigned char tmp=0; for(i=0;i<256;i++) { s[i]=i;//将0到255的互不重复的元素装入S盒 k[i]=key[i%Len]; } for(i=0;i<256;i++) { //第二个for循环根据密钥打乱S盒 //i确保S-box的每个元素都得到处理,j保证S-box的搅乱是随机的 j=(j+s[i]+k[i])%256; tmp=s[i]; s[i]=s[j]; //交换s[i]和s[j] s[j]=tmp; } } void rc4_crypt(unsigned char *s,unsigned char *Data,unsigned long Len) { int i=0,j=0,t=0; unsigned long k=0; unsigned char tmp; for(k=0;k<Len;k++)//循环中还改变了S盒 { i=(i+1)%256; j=(j+s[i])%256; tmp=s[i]; s[i]=s[j]; //交换s[x]和s[y] s[j]=tmp; t=(s[i]+s[j])%256; //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //每收到一个字节,就进行while循环。通过一定的算法定位S盒中的一个元素 Data[k]^=s[t];//并与输入字节异或,得到k } //如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文 } int main() { unsigned char s[256] = { 0 }, s2[256] = { 0 };//S-box char key[256] = { "justfortest" }; char pData[512] = "flag{woshidashabi}"; unsigned long len = strlen(pData); int i; printf("pData=%s\n", pData); printf("key=%s,length=%d\n\n", key, strlen(key)); rc4_init(s, (unsigned char*)key, strlen(key)); //已经完成了初始化 printf("完成对S[i]的初始化,如下:\n\n"); for (i = 0; i<256; i++) { printf("%02X,", s[i]); if (i && (i + 1) % 16 == 0)putchar('\n'); } printf("\n\n"); for (i = 0; i<256; i++) //用s2[i]暂时保留经过初始化的s[i],很重要的!!! { s2[i] = s[i]; } printf("已经初始化,现在加密:\n\n"); rc4_crypt(s, (unsigned char*)pData, len);//加密 printf("pData=%s\n\n", pData); printf("已经加密,现在解密:\n\n"); //rc4_init(s,(unsignedchar*)key,strlen(key));//初始化密钥 rc4_crypt(s2, (unsigned char*)pData, len);//解密 printf("pData=%s\n\n", pData); return 0; }