RC4加密与解密(MFC小工具)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_17017545/article/details/83181526

这里是通过RC4加密与解密来制作一个MFC小工具。
MFC框架代码可以通过VS自动生成,这里介绍。只涉及RC4加密解密与字节流转换同十六进制字符串相互转换。

RC4算法的原理很简单,包括初始化算法和伪随机子密码生成算法两大部分。

初始化函数

/*在初始化的过程中,密钥的主要功能是将S-box搅乱,i确保S-box的每个元素都得到处理,
j保证S-box的搅乱是随机的。而不同的S-box在经过伪随机子密码生成算法的处理后可以
得到不同的子密钥序列,将S-box和明文进行xor运算,得到密文,解密过程也完全相同。*/

//参数1是一个256长度的char型数组,定义为: unsigned char sBox[256];
//参数2是密钥,其内容可以随便定义:char key[256];
//参数3是密钥的长度,Len = strlen(key);

void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{
	int i = 0, j = 0;
	char k[256] = { 0 };
	unsigned char tmp = 0;
	for (i = 0; i<256; i++)
	{
		s[i] = i;
		k[i] = key[i%Len];
		// 如果输入长度小于256个字节,则进行轮转,直到填满例如输入密钥的是1,2,3,4,5   ,  那么填入的是1,2,3,4,5,1,2,3,4,5,1,2,3,4,5........

	}
	for (i = 0; i<256; i++)
	{
		j = (j + s[i] + k[i]) % 256;
		tmp = s[i];
		s[i] = s[j];//交换s[i]和s[j]
		s[j] = tmp;
	}
}

加解密


//参数1是上边rc4_init函数中,被搅乱的S-box;
//参数2是需要加密的数据data;
//参数3是data的长度.

void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
{
	int i = 0, j = 0, t = 0;
	unsigned long k = 0;
	unsigned char tmp;
	for (k = 0; k<Len; k++)
	{
		i = (i + 1) % 256;
		j = (j + s[i]) % 256;
		tmp = s[i];
		s[i] = s[j];//交换s[x]和s[y]
		s[j] = tmp;
		t = (s[i] + s[j]) % 256;
		Data[k] ^= s[t];
	}
}

字节流转换为十六进制字符串

void ByteToHexStr(const unsigned char* source, char* dest, int sourceLen)

{
	short i;
	unsigned char highByte, lowByte;


	for (i = 0; i < sourceLen; i++)
	{
		highByte = source[i] >> 4;
		lowByte = source[i] & 0x0f;


		highByte += 0x30;


		if (highByte > 0x39)
			dest[i * 2] = highByte + 0x07;
		else
			dest[i * 2] = highByte;


		lowByte += 0x30;
		if (lowByte > 0x39)
			dest[i * 2 + 1] = lowByte + 0x07;
		else
			dest[i * 2 + 1] = lowByte;
	}
	return;
}

十六进制字符串转换为字节流

void HexStrToByte(const char* source, unsigned char* dest, int sourceLen)
{
	short i;
	unsigned char highByte, lowByte;

	for (i = 0; i < sourceLen; i += 2)
	{
		highByte = toupper(source[i]);
		lowByte = toupper(source[i + 1]);


		if (highByte > 0x39)
			highByte -= 0x37;
		else
			highByte -= 0x30;


		if (lowByte > 0x39)
			lowByte -= 0x37;
		else
			lowByte -= 0x30;


		dest[i / 2] = (highByte << 4) | lowByte;
	}
	return;
}

加密按钮相应处理函数

void CRC4Dlg::OnBnClickedButtonEncryption()
{
	unsigned long len;
	unsigned char s[256] = { 0 };//S-box
	char Key[256];
	char Rc4_encode[256];		//存储Rc4加密之前的数据(明文)
	char HexData[512];			//存储16进制数据(明文RC4加密后会乱码,乱码转16进制可显示)

	memset(Key, 0, sizeof(char) * 256);
	memset(Rc4_encode, 0, sizeof(char) * 256);
	memset(HexData, 0, sizeof(char) * 512);

	CString str1, str2;
	GetDlgItem(IDC_EDIT_KEY)->GetWindowText(str1); //读取KEY值
	GetDlgItem(IDC_EDIT_SRC)->GetWindowText(str2); //读取明文值
	if ((str2 == ""))
	{
		MessageBox("Please enter text!");
		return;
	}
	if ((str1 == ""))
	{
		MessageBox("Please enter a key!");
		return;
	}
	strcpy(Key, str1);
	strcpy(Rc4_encode, str2);
	len = strlen(Rc4_encode);	//获取明文的字符串长度
	rc4_init(s, (unsigned char*)Key, strlen(Key));//已经完成了初始化
	rc4_crypt(s, (unsigned char*)Rc4_encode, len);// RC4加密,加密后的密文仍保存到Rc4_encode中(乱码)
	ByteToHexStr((unsigned char*)Rc4_encode, HexData, len); //乱码转十六进制 (16进制的字符串长度是乱码字符的两倍长)
	SetDlgItemText(IDC_EDIT_DEST, HexData);  //显示经过处理的密文(16进制)
}

解密按钮相应处理函数

void CRC4Dlg::OnBnClickedButtonDecryption()
{

	// TODO: 在此添加控件通知处理程序代码
	unsigned long len;
	unsigned char s[256] = { 0 };//S-box
	char Key[256];
	char Rc4_encode[256];		//存储Rc4解密之后的数据(明文)
	char HexData[512];			//存储16进制数据

	memset(Key, 0, sizeof(char) * 256);
	memset(Rc4_encode, 0, sizeof(char) * 256);
	memset(HexData, 0, sizeof(char) * 512);

	CString str1, str3;
	GetDlgItem(IDC_EDIT_KEY)->GetWindowText(str1); //读取KEY值
	GetDlgItem(IDC_EDIT_DEST)->GetWindowText(str3); //读取密文值

	if ((str3 == ""))
	{
		MessageBox("Please enter text!");
		return;
	}
	if ((str1 == ""))
	{
		MessageBox("Please enter a key!");
		return;
	}

	strcpy(Key, str1);
	strcpy(HexData, str3);  //Rc4_decode是密文值 (16进制)
	len = strlen(HexData);	//此时的16进制是有完整的加密后的乱码转换来的(包括乱码中间可能出现的 \0 字符)
	HexStrToByte(HexData,(unsigned char*)Rc4_encode,len);	  //十六进制转回之前的乱码
	rc4_init(s, (unsigned char*)Key, strlen(Key)); //初始化KEY
	rc4_crypt(s, (unsigned char*)Rc4_encode, len/2);//RC4解密   (解密后的乱码的长度是原来16进制的一半长)
	SetDlgItemText(IDC_EDIT_SRC, Rc4_encode);	//显示明文
}

最终MFC工具效果如下
在这里插入图片描述

参考链接:
RC4算法(百度百科)
C语言实现字节流与十六进制字符串的相互转换

获取MFC小工具完整代码请点我

猜你喜欢

转载自blog.csdn.net/qq_17017545/article/details/83181526
今日推荐