版权声明:本文为博主原创文章,未经博主允许不得转载。 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工具效果如下