“流密码(序列密码)与Rc4算法”
Rc4是一种序列密码,它是一种可变密钥长度、面向字节操作的序列密码,一个明文字节与一个密钥字节相异或产生一个密文字节。
算法原理:对于n = 8位长的字,即以一个字节为单位,此时N = 256,用从1到256个字节的可变长度密钥初始化一个256个字节的状态矢量arr,arr中的元素arr[0],arr[1],,,arr[255],自始至终置换后的arr包含0~255的所有8比特数,密钥流中的密钥key由arr中256个元素按一定方式选出一个元素来充当;每生成一个key值,arr中的元素就被重新置换一次。
初始化:
将arr中的元素初始化成arr[0] = 0,arr[1] = 1,,,,,arr[255] = 255,设密钥的长度为len,对于arr中的每个元素,由密钥K将arr[i]中的元素进行置换,由于只是第数组中的元素进行错乱的排列,数组arr中还包含0~255个元素。
//初始化的核心代码
for (int i = 0; i < 256; i++)
{
arr[i] = i;
K[i] = key[i % len];
//K数组是将key中的元素循环排列于数组中
}
//将数组中的数据进行错乱排列
for (int i = 0; i < 256; i++)
{
j = (j + arr[i] + K[i]) % 256;
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
加密时,将输入的明文与密钥进行异或,解密时,将密文与密钥进行异或。
//加密、解密的核心代码
for (size_t j = 0; j < len; j++)
{
x = (x + 1) % 256;
y = (y + arr[x]) % 256;
tmp = arr[x];
arr[x] = arr[y];
arr[y] = tmp;
t = (arr[x] + arr[y]) % 256;
ptr[j] ^= arr[t];
}
下面是完整的程序:
//头文件“stream.h”
#pragma once
//序列密码(流密码)
#include <string.h>
void Rc4(char* arr, char* ptr, size_t len) //进行加密或者解密,arr是密钥,ptr是明文
{
int x = -1;
int y = 0;
int t = 0;
char tmp = 0;
for (size_t j = 0; j < len; j++)
{
x = (x + 1) % 256;
y = (y + arr[x]) % 256;
tmp = arr[x];
arr[x] = arr[y];
arr[y] = tmp;
t = (arr[x] + arr[y]) % 256;
ptr[j] ^= arr[t];
}
}
void init(char *arr, char* key, size_t len) //初始化密钥,(密钥调度算法KSA)
{
int j = 0;
char K[256] = { 0 };
char tmp = 0;
for (int i = 0; i < 256; i++)
{
arr[i] = i;
K[i] = key[i % len];
//K数组是将key中的元素循环排列于数组中
}
//将数组中的数据进行错乱排列
for (int i = 0; i < 256; i++)
{
j = (j + arr[i] + K[i]) % 256;
tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
void menu(char *arr, char* key, char* ptr) //主菜单
{
char n, ch;
char arr1[256] = { 0 };
printf("**********************************\n");
printf("********* ——Rc4算法 *********\n");
printf("********* 1.加密与解密 *********\n");
printf("********* 0.退出 *********\n");
printf("**********************************\n");
printf("---请选择:");
scanf("%c", &n);
switch (n)
{
case '1':
printf("请输入需要加密的明文:");
fflush(stdin); //清除缓冲区
for (int i = 0; i < 256; i++)
{
if ((ch = getchar()) != '\n')
{
ptr[i] = ch;
}
else
{
break;
}
}
init(arr, key, strlen(key));
for (int i = 0; i < 256; i++) //保存初始化后的arr
{
arr1[i] = arr[i];
}
Rc4(arr, ptr, strlen(ptr)); //加密
printf("\n输出的密文为:");
printf("%s", ptr);
Rc4(arr1, ptr, strlen(ptr)); //解密
printf("\n输出的明文为:");
printf("%s", ptr);
break;
case '0':
exit(EXIT_FAILURE);
default:
break;
}
}
//源文件stream.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include "stream.h"
int main()
{
char arr[256] = { 0 };
char key[256] = {"zheshiyigemiyao"};
char ptr[256] = { 0 };
menu(arr, key, ptr);
system("pause");
return 0;
}
转载于:https://blog.51cto.com/10740590/1757519