C#开发RC4加密工具(超详细!保姆级!)

RC4 是一种流加密算法,用于数据的加密和解密,由Ron Rivest于1987年发明。它的名字即“Rivest Cipher 4”的缩写,发明者Ron Rivest 的姓氏以及它是一种流加密算法,被称为RC4。

RC4 算法的核心是一种伪随机数生成器,被称为伪随机数字发生器(PRNG),它使用一个 256 字节的密钥来生成密钥流。RC4 的加密和解密算法都是同一套算法。

RC4 算法操作原理:

1. 首先,使用密钥来初始化生成 RC4 算法的内部状态。如果密钥长于 256 个字节,则将其散列成 256 字节,并使用散列值来初始化内部状态。
2. 然后使用内部状态生成伪随机数流,它是由内部状态和输入密钥流生成的。
3. 最后,将明文与伪随机数流进行异或运算,得到密文。

解密过程与加密过程类似,只需将密文与伪随机数流异或即可得到明文。

本程序是用C语言开发了一个RC4算法的加密工具,开发环境:vs2022.

具体代码如下:

#pragma warning(disable:4996)//不加vs2022会一直报错4996!
#include <stdio.h>
#include <string.h>
void rc4(char* data, int length, const unsigned char* key, int keyLength) /*确保函数key指针指向的数据不被修改*/ {
    int i = 0, j = 0;
    unsigned char S[256];
    for (int k = 0; k < 256; ++k) {
        S[k] = k;
    }//初始化s盒
    for (int k = 0; k < 256; ++k) /*使用循环变量 k 遍历 S 盒的每个元素,从 0 到 255。*/ {
        j = (j + S[k] + key[k % keyLength]) % 256;//计算 S 盒中每个元素的新位置。其中,j 表示一个动态变化的下标,S[k] 表示 S 盒中当前位置的值,key[k % keyLength] 表示用密钥序列循环填充的数组。根据 RC4 的算法,每个下标 j 的生成,都和之前 j 的值、S[k] 值以及 key[] 相关,确保了下标 j 的高度随机性。
        unsigned char temp = S[k];
        S[k] = S[j];
        S[j] = temp;//交换 S 盒中 k 和 j 位置的元素。由于 j 的值是随机变化的,因此每个位置的交换是随机的,从而进一步增加了算法的安全性。
    }//生成S盒
    i = j = 0;
    for (int k = 0; k < length; ++k) /*对要加密/解密的数据逐个进行操作,进行 length 次循环(每个字节循环一次)。*/ {
        i = (i + 1) % 256;//将变量i加1,保证每次加密/解密的数据不同。
        j = (j + S[i]) % 256;//将变量j加上 S[i] 的值,然后对256取模,获取对应的S盒中新的字节。
        unsigned char temp = S[i];
        S[i] = S[j];
        S[j] = temp;将S[i]和S[j]进行交换,每次交换都改变S盒的顺序。
        unsigned char t = (S[i] + S[j]) % 256;
        data[k] ^= S[t];//计算 S[i] + S[j] 的值并对256取模,获得新的字节,用新的字节与要加密/解密的数据中的对应字节进行异或操作。
    }
}

int main() {
    int operation;//操作选择标量
    char FileName_yuan[260] = { 0 };//源文件
    char FileName_mubiao[260] = { 0 };//目标文件
    FILE* fp_yuan, * fp_mubiao, * fp_jiami, * fp_jiemi;//打开源文件、写入目标文件、打开已加密问价、写入解密后文件
    char key[256], Key2[256], file_cun[1024];//创建存放密钥的数组,用于存储文件内容的数组;
    int Bytes_duqu;//创建该变量用于存储读取文件中的每一字节

    while (1) {
        printf("——————————————欢迎使用本加密工具————————————————\n");
        printf("**************请选择要执行的操作:***************\n");
        printf("***************1. 文件加密***********************\n");
        printf("***************2. 文件解密***********************\n");
        printf("***************3. 字符串加密解密******************\n");
        printf("***************4. 退出***************************\n");
        printf("——————————————————————————————————————————————————\n");
        scanf("%d", &operation);

        switch (operation) {
        case 1:
            printf("请输入加密前文件名:");
            scanf("%s", FileName_yuan);
            printf("请输入加密后文件名:");
            scanf("%s", FileName_mubiao);

            fp_yuan = fopen(FileName_yuan, "rb");//读取源文件
            fp_mubiao = fopen(FileName_mubiao, "wb");//写入目标文件

            if (NULL == fp_yuan || NULL == fp_mubiao) {
                printf("打开文件失败\n");
                break;
            }

            printf("请输入密钥:");
            scanf("%s", key);

            while ((Bytes_duqu = fread(file_cun, 1, sizeof(file_cun), fp_yuan)) > 0)/*逐字节读取源文件内容读入到目标文件*/ {
                rc4(file_cun, Bytes_duqu, (const unsigned char*)key, strlen(key));/*调用RC4算法对文件内容进行逐字节加密*/
                fwrite(file_cun, 1, Bytes_duqu, fp_mubiao);/*将加密后的内容写入目标文件*/
            }
            fclose(fp_yuan);//关闭文件
            fclose(fp_mubiao);
            printf("加密成功!\n");
            break;

        case 2:
            printf("请输入已加密文件名:");
            scanf("%s", FileName_mubiao);
            fp_jiami = fopen(FileName_mubiao, "rb");//读取目标文件成为源文件
            fp_jiemi = fopen("已解密文件.txt", "wb");//创建解密后的目标文件

            if (NULL == fp_jiami || NULL == fp_jiemi) {
                printf("打开文件失败\n");
                break;
            }

            while (1) {
                printf("请输入解密密钥:");
                scanf("%s", Key2);
                // 密钥验证过程
                char check_Key1[256];
                int Times = 3;
                while (Times > 0) {
                    printf("请再次输入密钥以确认:");
                    scanf("%s", check_Key1);
                    if (strcmp(key, check_Key1) == 0) {
                        break;
                    }
                    else {
                        printf("密钥不正确,请重新输入,您还有%d次机会\n", Times - 1);
                        Times--;
                    }
                }
                if (Times == 0) {
                    printf("三次输入均不正确,已退出文件加密\n");
                    break;
                }
                int decrypted = 0;
                while ((Bytes_duqu = fread(file_cun, 1, sizeof(file_cun), fp_jiami)) > 0) {
                    rc4(file_cun, Bytes_duqu, (const unsigned char*)Key2, strlen(Key2));
                    fwrite(file_cun, 1, Bytes_duqu, fp_jiemi);
                    decrypted = 1;
                }

                if (decrypted) {
                    fclose(fp_jiami);
                    fclose(fp_jiemi);
                    printf("解密完成!\n");
                    break;
                }
                else {
                    printf("密钥错误,请重新输入\n");
                }
            }
            break;

        case 3:
            printf("请输入要加密的字符串:");
            scanf("%s", file_cun);
            printf("请输入密钥:");
            scanf("%s", key);
            rc4(file_cun, strlen(file_cun), (const unsigned char*)key, strlen(key));//调用Rc4进行加密操作
            printf("加密后的字符串:%s\n", file_cun);

            while (1) {
                printf("请输入密钥进行解密:");
                scanf("%s", Key2);
                //密钥验证过程
                char check_Key2[256];
                int Times2= 3;
                while (Times2 > 0) {
                    printf("请再次输入密钥以确认:");
                    scanf("%s", check_Key2);
                    if (strcmp(key, check_Key2) == 0) {
                        break;
                    }
                    else {
                        printf("密钥不正确,请重新输入,您还有 % d次机会\n", Times2- 1);
                        Times2--;
                    }
                }
                if (Times2 == 0) {
                    printf("三次输入均不正确,已退出字符串解密\n");
                    break;
                }
                rc4(file_cun, strlen(file_cun), (const unsigned char*)Key2, strlen(Key2));
                printf("解密成功!\n解密后的字符串:%s\n", file_cun);
                break;
            }
            break;

        case 4:
            printf("程序已退出,谢谢使用!\n");
            return 0;

        default:
            printf("无效的选择,请重新输入\n");
            break;
        }
    }

    return 0;
}

程序展示:

1.功能列表

 

2.文件加解密

 

3. 

 

ps:个人觉得该工具优化的差不多了(能实现字符串和文件加密),最近期末复习考试,呃.....剩下文件分割加密和shell编程实在不想肝了,C++实现RC4等考完试有时间写,欢迎大佬补充。

      

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

CSVN.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值