http://wzgyantai.blogbus.com/logs/31867065.html
近日由于用了RC4的知识,所以就对其进行了查阅,并且进行了实现,列于以下:
1.RC4算法介绍
RC4加密算法Ron Rivest(非常有名的非对称加密算法RSA三巨头之一)在1987年设计的,密钥长度可变的流加密算法簇。之所以称其为簇,是由于其核心部分的S-box长度可为任意,但一般为256字节。该算法的速度可以达到DES加密的10倍左右,且具有很高级别的非线性。RC4起初是用于保护商业机密的。但是在1994年9月,它的算法被发布在互联网上,也就不再有什么商业机密了。RC4也被叫做ARC4(Alleged RC4——所谓的RC4),因为RSA从来就没有正式发布过这个算法。
备注:RC4是对称密钥加密算法,而RSA是非对称的加密算法。由于RC4算法加密是采用的xor,所以,一旦子密钥序列出现了重复,密文就有可能被破解。那么,RC4算法生成的子密钥序列是否会出现重复呢?由于存在部分弱密钥,使得子密钥序列在不到100万字节内就发生了完全的重复,如果是部分重复,则可能在不到10万字节内就能发生重复,因此,推荐在使用RC4算法时,必须对加密密钥进行测试,判断其是否为弱密钥。根据目前的分析结果,没有任何的分析对于密钥长度达到128位的RC4有效,所以,RC4是目前最安全的加密算法之一。
2. RC4的C语言实现
#include<stdio.h>
#include<memory.h>
#include<string.h>
#include<stdlib.h>
#define buf_size 1024
typedef struct rc4_key
{
unsigned char state[256];
unsigned char x;
unsigned char y;
} rc4_key;
void swap_byte(unsigned char*x,unsigned char*y)
{
*x=*x^*y;
*y=*x^*y;
*x=*x^*y;
}
void prepare_key(unsigned char *key_data_ptr, int key_data_len, rc4_key *key)
{
int i;
unsigned char t;
unsigned char swapByte;
unsigned char index1;
unsigned char index2;
unsigned char* state;
short counter;
state = &key->state[0];
for(counter = 0; counter < 256; counter++)
state[counter] = counter;
key->x = 0;
key->y = 0;
index1 = 0;
index2 = 0;
for(counter = 0; counter < 256; counter++)
{
index2 = (key_data_ptr[index1] + state[counter] + index2) % 256;
swap_byte(&state[counter], &state[index2]);
index1 = (index1 + 1) % key_data_len;
}
}
void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key)
{
unsigned char t;
unsigned char x;
unsigned char y;
unsigned char* state;
unsigned char xorIndex;
short counter;
x = key->x;
y = key->y;
state = &key->state[0];
for(counter = 0; counter < buffer_len; counter++)
{
x = (x + 1) % 256;
y = (state[x] + y) % 256;
swap_byte(&state[x], &state[y]);
xorIndex = (state[x] + state[y]) % 256;
buffer_ptr[counter] ^= state[xorIndex];
}
key->x = x;
key->y = y;
}
3.使用方法
RC4的加密和解密使用同一个流程,密钥(其实是Seed姑且称之为密钥+明文=密文,密钥(其实是Seed姑且称之为密钥)+密文=明文(+此处为象征意义,不是真的加法),从下面的调用示例也可以看出来
调用示例:
int main()
{
struct rc4_key s;
unsigned char*seed=(unsigned char*)malloc(4);
seed="1234";
unsigned char*myinput=(unsigned char*)malloc(17);
unsigned char*temp="nankai university";
int i=0;
for(i=0;i<17;i++)
{
myinput[i]=*(temp+i);
}
printf("orignal text:%s\n",myinput);
//加密
prepare_key(seed,4,&s);
rc4(myinput,17,&s);
printf("secret string:");
for(i=0;i<17;i++)
{
printf("%x ",myinput[i]);
}
printf("\ndecrypt the secret string,the result is:");
//解密
prepare_key(seed,4,&s);
rc4(myinput,17,&s);
printf("%s\n",myinput);
}
return 1;
}
注:函数同样支持使用十六机制的非可打印字符进行加密解密运算
http://blog.csdn.net/csu_jsj_wlp/article/details/8189023
自已写的,代码质量肯定不是很高,存在优化空间是肯定的,可能也存在隐藏的漏洞。
以下代码侧重于对数据的加密和解密的算法部分,其他部分的问题没处理,仅供参考。
编译器用的是:C-Free 5.0
直接源代码:
- //RC4算法对数据的加密和解密
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <conio.h>
- #include <iostream>
- using namespace std;
- /*函数声明*/
- void InitSbox(unsigned char sbox[]);
- void KeyExpansion(unsigned char key[], char *k, int len);
- void UpsetSbox(unsigned char sbox[], unsigned char key[]);
- void DataProcess(unsigned char sbox[], FILE *fp1, FILE *fp2);
- void DataEncrypt(char *k, unsigned char *key, unsigned char *sbox, FILE *fp1, FILE *fp2);
- void DataDecrypt(char *k1, unsigned char *key, unsigned char *sbox, FILE *fp1, FILE *fp2);
- /*初始化S盒*/
- void InitSbox(unsigned char sbox[]){
- for(int i = 0; i < 256; i++) sbox[i] = i;
- }
- /*密钥填充256数组*/
- void KeyExpansion(unsigned char key[], char *k, int len){
- if(len <= 256){
- for(int i = 0; i < 256; i++) key[i] = k[i % len];
- }
- if(len > 256){
- for(int i = 0; i < 256; i++) key[i] = k[i];
- }
- }
- /*打乱S盒*/
- void UpsetSbox(unsigned char sbox[], unsigned char key[]){
- int j = 0;
- unsigned char temp;
- int n;
- for(int i = 0; i < 256; i++){
- n = j + (int)sbox[i] + (int)key[i];
- j = n % 256;
- temp = sbox[i];
- sbox[i] = sbox[j];
- sbox[j] = temp;
- }
- }
- /*加解密数据*/
- void DataProcess(unsigned char sbox[], FILE *fp1, FILE *fp2){
- int i, j;
- i = 0; j = 0;
- char ch = fgetc(fp1);
- while(ch != EOF){
- i = (i + 1) % 256;
- int temp2 = j + (int)sbox[i];
- j = temp2 % 256;
- unsigned char temp;
- temp = sbox[i];
- sbox[i] = sbox[j];
- sbox[j] = temp;
- int temp1 = (int)sbox[i] + (int)sbox[j];
- int t = temp1 % 256;
- char k = sbox[t];
- char cipherchar = ch ^ k;
- fputc(cipherchar, fp2);
- ch = fgetc(fp1);
- }
- }
- /*加密总函数*/
- void DataEncrypt(char *k, unsigned char *key, unsigned char *sbox, FILE *fp1, FILE *fp2) {
- int len = strlen(k);
- KeyExpansion(key, k, len);
- InitSbox(sbox);
- UpsetSbox(sbox, key);
- DataProcess(sbox, fp1, fp2);
- fclose(fp1);
- fclose(fp2);
- printf("\n加密成功!\n\n");
- }
- /*解密总函数*/
- void DataDecrypt(char *k1, unsigned char *key, unsigned char *sbox, FILE *fp1, FILE *fp2) {
- int len = strlen(k1);
- KeyExpansion(key, k1, len);
- InitSbox(sbox);
- UpsetSbox(sbox, key);
- DataProcess(sbox, fp1, fp2);
- fclose(fp1);
- fclose(fp2);
- printf("\n解密成功!\n\n");
- }
- main(){
- char *k = (char *)malloc(25 * sizeof(char));
- char *k1 = (char *)malloc(25 * sizeof(char));
- unsigned char key[256] = {0x00};
- unsigned char sbox[256] = {0x00};
- FILE *fp1, *fp2;
- int flag = 1;
- int choice;
- do{
- printf("*****************************RC4加密解密文件************************************");
- printf("\n");
- printf(" 1.加密文件\n\n");
- printf(" 2.解密文件\n\n");
- printf(" 3.退出\n\n");
- printf("请选择要进行的操作:");
- scanf("%d",&choice);
- switch(choice){
- case 1: fp1 = fopen("源文件.txt","r");
- if(fp1 == NULL){
- printf("打开源文件失败!\n");
- getchar();
- exit(0);
- }
- fp2 = fopen("加密后文件.txt","w");
- if(fp2 == NULL){
- printf("打开加密后文件失败!\n");
- getchar();
- exit(0);
- }
- printf("\n请输入加密密钥:");
- cin >> k;
- DataEncrypt(k, key, sbox, fp1, fp2);
- break;
- case 2: fp1 = fopen("加密后文件.txt","r");
- if(fp1 == NULL){
- printf("打开加密后文件失败!\n");
- getchar();
- exit(0);
- }
- fp2 = fopen("解密后文件.txt","w");
- if(fp2 == NULL){
- printf("打开解密后文件失败!\n");
- getchar();
- exit(0);
- }
- printf("\n请输入解密密钥:");
- cin >> k1;
- DataDecrypt(k1, key, sbox, fp1, fp2);
- break;
- case 3: flag = 0;break;
- default : printf("\n操作不合法!\n\n");
- }
- }while(flag);
- }
运行结果:
1.源文件为:
2.进入加密模块,输入加密密钥:helloword
3.加密后文件:
4.进入解密模块,输入解密密钥:helloword
5.解密后文件: