RC加密解密算法C源代码

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

 

直接源代码:

[cpp]  view plain copy
  1. //RC4算法对数据的加密和解密  
  2.   
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <string.h>  
  6. #include <conio.h>  
  7. #include <iostream>  
  8.   
  9. using namespace std;  
  10.   
  11. /*函数声明*/  
  12. void InitSbox(unsigned char sbox[]);   
  13. void KeyExpansion(unsigned char key[], char *k, int len);  
  14. void UpsetSbox(unsigned char sbox[], unsigned char key[]);  
  15. void DataProcess(unsigned char sbox[], FILE *fp1, FILE *fp2);  
  16. void DataEncrypt(char *k, unsigned char *key, unsigned char *sbox, FILE *fp1, FILE *fp2);  
  17. void DataDecrypt(char *k1, unsigned char *key, unsigned char *sbox, FILE *fp1, FILE *fp2);  
  18.   
  19. /*初始化S盒*/  
  20. void InitSbox(unsigned char sbox[]){  
  21.     for(int i = 0; i < 256; i++)  sbox[i] = i;  
  22. }  
  23.   
  24. /*密钥填充256数组*/  
  25. void KeyExpansion(unsigned char key[], char *k, int len){  
  26.     if(len <= 256){  
  27.         for(int i = 0; i < 256; i++) key[i] = k[i % len];  
  28.     }  
  29.     if(len > 256){  
  30.         for(int i = 0; i < 256; i++) key[i] = k[i];  
  31.     }  
  32. }  
  33.   
  34. /*打乱S盒*/   
  35. void UpsetSbox(unsigned char sbox[], unsigned char key[]){  
  36.     int j = 0;  
  37.     unsigned char temp;  
  38.     int n;  
  39.     for(int i = 0; i < 256; i++){  
  40.         n = j + (int)sbox[i] + (int)key[i];  
  41.         j = n % 256;  
  42.         temp = sbox[i];  
  43.         sbox[i] = sbox[j];  
  44.         sbox[j] = temp;  
  45.     }  
  46. }  
  47.   
  48. /*加解密数据*/   
  49. void DataProcess(unsigned char sbox[], FILE *fp1, FILE *fp2){  
  50.     int i, j;  
  51.     i = 0; j = 0;  
  52.     char ch = fgetc(fp1);  
  53.     while(ch != EOF){  
  54.         i = (i + 1) % 256;  
  55.         int temp2 = j + (int)sbox[i];  
  56.         j = temp2 % 256;  
  57.         unsigned char temp;  
  58.         temp = sbox[i];  
  59.         sbox[i] = sbox[j];  
  60.         sbox[j] = temp;  
  61.         int temp1 = (int)sbox[i] + (int)sbox[j];  
  62.         int t = temp1 % 256;  
  63.         char k = sbox[t];  
  64.         char cipherchar = ch ^ k;  
  65.         fputc(cipherchar, fp2);  
  66.         ch = fgetc(fp1);  
  67.     }  
  68. }  
  69.   
  70. /*加密总函数*/  
  71. void DataEncrypt(char *k, unsigned char *key, unsigned char *sbox, FILE *fp1, FILE *fp2) {  
  72.     int len = strlen(k);  
  73.     KeyExpansion(key, k, len);  
  74.     InitSbox(sbox);  
  75.     UpsetSbox(sbox, key);  
  76.     DataProcess(sbox, fp1, fp2);  
  77.     fclose(fp1);  
  78.     fclose(fp2);  
  79.     printf("\n加密成功!\n\n");  
  80. }  
  81.   
  82. /*解密总函数*/   
  83. void DataDecrypt(char *k1, unsigned char *key, unsigned char *sbox, FILE *fp1, FILE *fp2) {  
  84.     int len = strlen(k1);  
  85.     KeyExpansion(key, k1, len);  
  86.     InitSbox(sbox);  
  87.     UpsetSbox(sbox, key);  
  88.     DataProcess(sbox, fp1, fp2);  
  89.     fclose(fp1);  
  90.     fclose(fp2);  
  91.     printf("\n解密成功!\n\n");  
  92. }  
  93.   
  94. main(){  
  95.     char *k = (char *)malloc(25 * sizeof(char));  
  96.     char *k1 = (char *)malloc(25 * sizeof(char));  
  97.     unsigned char key[256] = {0x00};  
  98.     unsigned char sbox[256] = {0x00};  
  99.     FILE *fp1, *fp2;  
  100.     int flag = 1;  
  101.     int choice;  
  102.     do{  
  103.         printf("*****************************RC4加密解密文件************************************");  
  104.         printf("\n");   
  105.         printf("                             1.加密文件\n\n");  
  106.         printf("                             2.解密文件\n\n");  
  107.         printf("                             3.退出\n\n");   
  108.         printf("请选择要进行的操作:");  
  109.         scanf("%d",&choice);  
  110.         switch(choice){  
  111.             case 1: fp1 = fopen("源文件.txt","r");  
  112.                     if(fp1 == NULL){  
  113.                         printf("打开源文件失败!\n");  
  114.                         getchar();  
  115.                         exit(0);  
  116.                     }  
  117.                     fp2 = fopen("加密后文件.txt","w");  
  118.                     if(fp2 == NULL){  
  119.                         printf("打开加密后文件失败!\n");  
  120.                         getchar();  
  121.                         exit(0);  
  122.                     }  
  123.                     printf("\n请输入加密密钥:");  
  124.                     cin >> k;  
  125.                     DataEncrypt(k, key, sbox, fp1, fp2);  
  126.                     break;  
  127.             case 2: fp1 = fopen("加密后文件.txt","r");  
  128.                     if(fp1 == NULL){  
  129.                         printf("打开加密后文件失败!\n");  
  130.                         getchar();  
  131.                         exit(0);  
  132.                     }  
  133.                     fp2 = fopen("解密后文件.txt","w");  
  134.                     if(fp2 == NULL){  
  135.                         printf("打开解密后文件失败!\n");  
  136.                         getchar();  
  137.                         exit(0);  
  138.                     }  
  139.                     printf("\n请输入解密密钥:");  
  140.                     cin >> k1;  
  141.                     DataDecrypt(k1, key, sbox, fp1, fp2);  
  142.                     break;  
  143.             case 3: flag = 0;break;  
  144.             default : printf("\n操作不合法!\n\n");  
  145.         }  
  146.     }while(flag);  
  147. }  


 

运行结果:

1.源文件为:

2.进入加密模块,输入加密密钥:helloword

3.加密后文件:

4.进入解密模块,输入解密密钥:helloword

5.解密后文件:


某同学在宿舍公用计算机上面使用文本文件来记录每天的心情故事,但是宿舍公用计算机不能设置密码,同学担心自己的日记被偷看,特委托你来完成如下加密程序: 该程序是一个可加密数据的日记记录工具,具有如下功能要求: 1. 运行系统后,系统给出三个选项:1)新增日记;2)阅读日记;3)退出系统 2. 选择功能1)后,系统提示用户输入日记文件名称和路径,并创建文本文件;同时,用户输入两个字符a和b,作为密钥;创建文件后,用户开始输入日记内容,日记内容为文本形式,将日记内容加密,然后将加密后的内容写入文件中; 3. 选择功能2)后,系统提示用户输入要打开的日记文件的路径和名称,打开文件后,读取文件中的密文,解密后显示出来; 4. 加密算法推荐大家采用简单的文本加密算法来实现,算法思想如下,从明文读入一个字符(英文),使用密钥a与该字符做异或操作,将结果作为密文保存下来,再读入第二个字符,使用密钥b与该字符做异或操作,同样保存结果,以此类推加密全文;解密过程可将密文作为输入完成整个加密过程,返回就是明文。如果同学们有兴趣加密中文,那么可将中文的高八位使用密钥a加密,低八位使用密钥b加密,完成加密过程。 这个加密算法需要使用C语言的位运算运算符,包括:& 按位与、| 按位或、^ 按位异或、~ 取反、<> 右移。 那么本算法中的异或可用如下方法完成,c为明文中取得的一个字符,该字符加密(解密)指令如下: c = plaintext[i]; //i+1是奇数使用密钥a,是偶数采用密钥b cipher[i] = c ^ a; 那么在cipher[i]中保存的就是c的密文。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值