加密原理
Rc4加密步骤
- 1、先初始化状态向量S(256个字节,用来作为密钥流生成的种子1)
按照升序,给每个字节赋值0,1,2,3,4,5,6…,254,255
- 2、初始密钥(由用户输入),长度任意
如果输入长度小于256个字节,则进行轮转,直到填满
例如输入密钥的是1,2,3,4,5 , 那么填入的是1,2,3,4,5,1,2,3,4,5,1,2,3,4,5…
由上述轮转过程得到256个字节的向量T(用来作为密钥流生成的种子2)
- 3、开始对状态向量S进行置换操作(用来打乱初始种子1)
按照下列规则进行
从第零个字节开始,执行256次,保证每个字节都得到处理
j = 0;
for (i = 0 ; i < 256 ; i++){
j = (j + S[i] + T[i]) mod 256;
swap(S[i] , S[j]);
}
这样处理后的状态向量S几乎是带有一定的随机性了
- 4、最后是秘钥流的生成与加密,很多人在这里不是特别理解,别的博客也没有写的很简洁明了
假设我的明文字节数是datalength=1024个字节(当然可以是任意个字节)
i=0;
j=0;
while(datalength–){//相当于执行1024次,这样生成的秘钥流也是1024个字节
i = (i + 1) mod 256;
j = (j + S[i]) mod 256;
swap(S[i] , S[j]);
t = (S[i] + S[j]) mod 256;
k = S[t];这里的K就是当前生成的一个秘钥流中的一位
//可以直接在这里进行加密,当然也可以将密钥流保存在数组中,最后进行异或就ok
data[]=data[]^k; //进行加密,"^"是异或运算符
}
解密按照前面写的,异或两次就是原文,所以只要把密钥流重新拿过来异或一次就能得到原文了
C实现
#include<stdio.h>
#include<random>
#include<time.h>
#include<string.h>
#define MAX 65534
int S[256]; //向量S
char T[256]; //向量T
int Key[256]; //随机生成的密钥
int KeyStream[MAX]; //密钥
char PlainText[MAX];
char CryptoText[MAX];
const char *WordList = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
void init_S()
// 初始化S;
{
for(int i = 0; i < 256; i++){
S[i] = i;
}
}
void init_Key(){
// 初始密钥
int index;
srand(time(NULL)); //根据当前时间,作为种子
int keylen = int(double(random())/double(RAND_MAX)*256); //随机获取一个密钥的长度
for(int i = 0; i < keylen; i++){
index = int(double(random())/double(RAND_MAX)*63); //生产密钥数组
Key[i] = WordList[index];
}
int d;
for(int i = 0; i < 256; i++){ //初始化T[]
T[i] = Key[i%keylen];
}
}
void permute_S()
{
// 置换S;
int temp;
int j = 0;
for(int i = 0; i < 256; i++){
j = (j + S[i] + T[i]) % 256;
temp = S[i];
S[i] = S[j];
S[j] = temp;
}
}
void create_key_stream(char *text, int textLength)
{
// 生成密钥流
int i,j;
int temp, t, k;
int index = 0;
i = j = 0;
while(textLength --){ //生成密钥流
i = (i+1)%256;
j = (j + S[i]) % 256;
temp = S[i];
S[i] = S[j];
S[j] = temp;
t = (S[i] + S[j]) % 256;
KeyStream[index] = S[t];
index ++;
}
}
void Rc4EncryptText(char *text)
{
//加密 && 解密
int textLength = strlen(text);
init_S();
init_Key();
permute_S();
create_key_stream(text, textLength);
int plain_word;
printf("============开始加密============:
密文:");
for(int i = 0; i < textLength; i++){
CryptoText[i] = char(KeyStream[i] ^ text[i]); //加密
}
for(int i = 0; i < textLength; i++){
printf("%c", CryptoText[i]);
}
printf("
============加密完成============
============开始解密============
明文:");
for(int i = 0; i < textLength; i++){
PlainText[i] = char(KeyStream[i] ^ CryptoText[i]); //解密
}
for(int i = 0; i < textLength; i++){
printf("%c", PlainText[i]);
}
printf("
============解密完成============
");
printf("
");
}
int main()
{
char text[] = "卜算子·见也如何暮 宋代:石孝友 见也如何暮。别也如何遽。别也应难见也难,后会难凭据。 去也如何去。住也如何住。住也应难去也难,此际难分付。 ";
Rc4EncryptText(text);
return 0;
}