VC实现数据的加密和解密(MD5加密/DES/RSA加密解密)

本文介绍了在VC环境下实现数据加密解密的方法,包括MD5、DES和RSA算法。提供了源代码实现,重点讨论了MD5的四轮变换过程。此外,还涉及了对话框中的加密解密功能控制,如单选框和按钮的响应处理。
摘要由CSDN通过智能技术生成

   

VC实现数据的加密和解密

由于生产实习的时间有限,加上自己这段时间致力于考研,因此,仅仅是实现了通过MD5/DES/RSA的简单的字符串的加密解密,希望有兴趣的兄弟姐妹能够完善它。

主要的程序如下:

1)、MD5

// MD5.h: interface for the CMD5 class.
//
//

#if !defined(AFX_MD5_H__EA6A200B_1336_43F3_B866_2A2E28D54560__INCLUDED_)
#define AFX_MD5_H__EA6A200B_1336_43F3_B866_2A2E28D54560__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//测试判别:摘自http://www.ietf.org/rfc/rfc1321.txt
/*
MD5 ("") = d41d8cd98f00b204e9800998ecf8427e
MD5 ("a") = 0cc175b9c0f1b6a831c399e269772661
MD5 ("abc") = 900150983cd24fb0d6963f7d28e17f72
MD5 ("message digest") = f96b697d7cb7938d525a2f31aaf161d0
MD5 ("abcdefghijklmnopqrstuvwxyz") = c3fcd3d76192e4007dfb496cca67e13b
MD5 ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789") =
d174ab98d277d9f5a5611c2c9f419d9f
MD5 ("123456789012345678901234567890123456789012345678901234567890123456
78901234567890") = 57edf4a22be3c955ac49da2e2107b67a
*/
//补充MD5算法是不可逆的算法,也就是说不存在解密,惟有暴力解密才可以解密。 该算法主要是对摘要进行加密
//主要是用于用户口令的加密,例如:UNIX里面用户口令保存都是也MD5加密后进行存储,当用户登录时,首先要对输
//入的口令进行MD5进行加密,然后再和存储的MD5加密用户口令进行比较
#include <string>
using namespace std;

class CMD5
{
public:
 //CONSTRUCTOR
 CMD5();
 //对基类的虚函数进行实现
 void AddData(char const* pcData, int iDataLength);
 void FinalDigest(char* pcDigest);
 void Reset();
 void DigestFile(string const& readFile, char* pcDigest);
 virtual ~CMD5();
protected:
 //设置附上64位的消息长度
 enum { BLOCKSIZE=64 };
 BOOL m_bAddData;
private:
 //总共要经过4轮变换
 enum { MD128LENGTH=4 };
 //设定每次读取文件长度长度为1024位,数据长度为384(可以i自己设定)
 enum { DATA_LEN=384, BUFF_LEN=1024 };
 //四个32-位的变量,数值必须为正整数,就是A,B,C,D
 unsigned int m_auiBuf[4];
 unsigned int m_auiBits[2];
 //获取M0-〉M64消息的64个子分组
 unsigned char m_aucIn[64];

 //主循环要经过四轮变换,第一轮要经过16次操作,都是由下面的基本运算组成
 static unsigned int F(unsigned int x, unsigned int y, unsigned int z);
 static unsigned int G(unsigned int x, unsigned int y, unsigned int z);
 static unsigned int H(unsigned int x, unsigned int y, unsigned int z);
 static unsigned int I(unsigned int x, unsigned int y, unsigned int z);

 //对FF,GG,HH,II函数进行定义
 //具体的参数说明:第一个参数为:F1、F2、F3、F4方法的选择,第二个参数为:运算的结果,即初始化的参数
 //第三、四、五个参数为初始化的参数,具体为a,b,c,d中的不同的三个,第六个参数为:消息的第J个子分组,第七个参数为循环左移S位
 static void MD5STEP(unsigned int (*f)(unsigned int x, unsigned int y, unsigned int z),
  unsigned int& w, unsigned int x, unsigned int y, unsigned int z, unsigned int data, unsigned int s);
 //MD5四轮变换算法,具体是对四轮中的每一轮进行16次运算
 void MD5Transform();
};
//具体的函数可以参考http://www.ietf.org/rfc/rfc1321.txt,The MD5 Message-Digest Algorithm(MD5摘要加密算法)
//第一个非线性函数,即所谓的F函数:F(X,Y,Z) = (X&Y)|((~X)&Z)
inline unsigned int CMD5::F(unsigned int x, unsigned int y, unsigned int z)
{
 return (x & y | ~x & z);
}
//第二个非线性函数,即所谓的G函数:G(X,Y,Z) = (X&Z)|(Y&(~Z))
inline unsigned int CMD5::G(unsigned int x, unsigned int y, unsigned int z)
{
 return F(z, x, y);
}
//第三个非线性函数,即所谓的H函数:H(X,Y,Z) = X XOR Y XOR Z
inline unsigned int CMD5::H(unsigned int x, unsigned int y, unsigned int z)
{
 return x ^ y ^ z;
}
//第四个非线性函数,即所谓的I函数:I(X,Y,Z) = Y XOR (X | (~Z))
inline unsigned int CMD5::I(unsigned int x, unsigned int y, unsigned int z)
{
 return (y ^ (x | ~z));
}
//
inline void CMD5::MD5STEP(unsigned int (*f)(unsigned int x, unsigned int y, unsigned int z),
 unsigned int& w, unsigned int x, unsigned int y, unsigned int z, unsigned int data, unsigned int s)
{
 w += f(x, y, z) + data;
 w = w << s | w >> (32-s);
 w += x;
}
#endif // !defined(AFX_MD5_H__EA6A200B_1336_43F3_B866_2A2E28D54560__INCLUDED_)
// MD5.cpp: implementation of the CMD5 class.
//
//

#include "stdafx.h"
#include "EncryAndDecrypt.h"
#include "MD5.h"
#include "FileBuffer.h"
#include <fstream>
#include <strstream>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//
// Construction/Destruction
//
//初始化变量值
CMD5::CMD5():m_bAddData(false)
{
 //对四个32位的变量进行初始化
 m_auiBuf[0] = 0x67452301;
 m_auiBuf[1] = 0xefcdab89;
 m_auiBuf[2] = 0x98badcfe;
 m_auiBuf[3] = 0x10325476;
 m_auiBits[0] = 0;
 m_auiBits[1] = 0;
}

CMD5::~CMD5()
{
}
void CMD5::AddData(char const* pcData, int iDataLength)
{
 if(iDataLength < 0)
  AfxMessageBox("MD5文件加密失败!,数据的长度必须大于0");
 unsigned int uiT;
 //更新位长度
 uiT = m_auiBits[0];
 //参考MD5Update函数
 if((m_auiBits[0] = uiT + ((unsigned int)iDataLength << 3)) < uiT)
  m_auiBits[1]++;
 m_auiBits[1] += iDataLength >> 29;
 uiT = (uiT >> 3) & (BLOCKSIZE-1); //转化为字节
 //处理奇数块
 if(uiT != 0)
 {
  unsigned char *puc = (unsigned char *)m_aucIn + uiT;
  uiT = BLOCKSIZE - uiT;
  if(iDataLength < uiT)
  {
   memcpy(puc, pcData, iDataLength);
   return;
  }
  memcpy(puc, pcData, uiT);
  MD5Transform();
  pcData += uiT;
  iDataLength -= uiT;
 }
 //处理长度为64字节数据块
 while(iDataLength >= BLOCKSIZE)
 {
  memcpy(m_aucIn, pcData, BLOCKSIZE);
  MD5Transform();
  pcData += BLOCKSIZE;
  iDataLength -= BLOCKSIZE;
 }
 //处理余下的数据
 memcpy(m_aucIn, pcData, iDataLength);
 //设置标志位
 m_bAddData = true;
}
void CMD5::FinalDigest(char* pcDigest)
{
 if(m_bAddData == false)
  AfxMessageBox("MD5文件加密失败!,没有数据被添加");
 unsigned int uiCount;
 unsigned char* puc;
 //参考MD5Update函数
 //计算字节对64取余运算
 uiCount = (m_auiBits[0] >> 3) & (BLOCKSIZE-1);
 //参考static unsigned char PADDING[64]~~即对对一个填充位设置为0x80
 puc = m_aucIn + uiCount;
 *puc++ = 0x80;
 //同时要通过填充来达到64个字节
 uiCount = BLOCKSIZE - uiCount - 1;
 //填充到64位长度
 //假如填充的长度未达到64位长度
 if(uiCount < 8)
 {
  //首先要填充前面64个字节
  memset(puc, 0, uiCount);
  MD5Transform();
  //然后要填充后面的56个字节
  memset(m_aucIn, 0, BLOCKSIZE-8);
 }
 //已经达到64位
 else
 {
  //直接填充56个字节
  memset(puc, 0, uiCount - 8);
 }
 //添加位长度同时进行MD5变换
 ((unsigned int*)m_aucIn)[(BLOCKSIZE>>2)-2] = m_auiBits[0];
 ((unsigned int*)m_aucIn)[(BLOCKSIZE>>2)-1] = m_auiBits[1];
 MD5Transform();
 memcpy(pcDigest, m_auiBuf, MD128LENGTH<<2);
 //重新设置大小
 Reset();
}
void CMD5::Reset()
{
 //对四个32位的变量重新设置
 m_auiBuf[0] = 0x67452301;
 m_auiBuf[1] = 0xefcdab89;
 m_auiBuf[2] = 0x98badcfe;
 m_auiBuf[3] = 0x10325476;
 m_auiBits[0] = 0;
 m_auiBits[1] = 0;
 //重设标志
 m_bAddData = false;
}

//MD5四轮变换算法,具体的64次运算过程如下
void CMD5::MD5Transform()
{
 unsigned int* puiIn = (unsigned int*)m_aucIn;
 register unsigned int a, b, c, d;
 a = m_auiBuf[0];
 b = m_auiBuf[1];
 c = m_auiBuf[2];
 d = m_auiBuf[3];
 //第一轮
 MD5STEP(F, a, b, c, d, puiIn[0] + 0xd76aa478, 7);
 MD5STEP(F, d, a, b, c, puiIn[1] + 0xe8c7b756, 12);
 MD5STEP(F, c, d, a, b, puiIn[2] + 0x242070db, 17);
 MD5STEP(F, b, c, d, a, puiIn[3] + 0xc1bdceee, 22);
 MD5STEP(F, a, b, c, d, puiIn[4] + 0xf57c0faf, 7);
 MD5STEP(F, d, a, b, c, puiIn[5] + 0x4787c62a, 12);
 MD5STEP(F, c, d, a, b, puiIn[6] + 0xa8304613, 17);
 MD5STEP(F, b, c, d, a, puiIn[7] + 0xfd469501, 22);
 MD5STEP(F, a, b, c, d, puiIn[8] + 0x698098d8, 7);
 MD5STEP(F, d, a, b, c, puiIn[9] + 0x8b44f7af, 12);
 MD5STEP(F, c, d, a, b, puiIn[10] + 0xffff5bb1, 17);
 MD5STEP(F, b, c, d, a, puiIn[11] + 0x895cd7be, 22);
 MD5STEP(F, a, b, c, d, puiIn[12] + 0x6b901122, 7);
 MD5STEP(F, d, a, b, c, puiIn[13] + 0xfd987193, 12);
 MD5STEP(F, c, d, a, b, puiIn[14] + 0xa679438e, 17);
 MD5STEP(F, b, c, d, a, puiIn[15] + 0x49b40821, 22);
 //第二轮
 MD5STEP(G, a, b, c, d, puiIn[1] + 0xf61e2562, 5);
 MD5STEP(G, d, a, b, c, puiIn[6] + 0xc040b340, 9);
 MD5STEP(G, c, d, a, b, puiIn[11] + 0x265e5a51, 14);
 MD5STEP(G, b, c, d, a, puiIn[0] + 0xe9b6c7aa, 20);
 MD5STEP(G, a, b, c, d, puiIn[5] + 0xd62f105d, 5);
 MD5STEP(G, d, a, b, c, puiIn[10] + 0x02441453, 9);
 MD5STEP(G, c, d, a, b, puiIn[15] + 0xd8a1e681, 14);
 MD5STEP(G, b, c, d, a, puiIn[4] + 0xe7d3fbc8, 20);
 MD5STEP(G, a, b, c, d, puiIn[9] + 0x21e1cde6, 5);
 MD5STEP(G, d, a, b, c, puiIn[14] + 0xc33707d6, 9);
 MD5STEP(G, c, d, a, b, puiIn[3] + 0xf4d50d87, 14);
 MD5STEP(G, b, c, d, a, puiIn[8] + 0x455a14ed, 20);
 MD5STEP(G, a, b, c, d, puiIn[13] + 0xa9e3e905, 5);
 MD5STEP(G, d, a, b, c, puiIn[2] + 0xfcefa3f8, 9);
 MD5STEP(G, c, d, a, b, puiIn[7] + 0x676f02d9, 14);
 MD5STEP(G, b, c, d, a, puiIn[12] + 0x8d2a4c8a, 20);
 //第三轮
 MD5STEP(H, a, b, c, d, puiIn[5] + 0xfffa3942, 4);
 MD5STEP(H, d, a, b, c, puiIn[8] + 0x8771f681, 11);
 MD5STEP(H, c, d, a, b, puiIn[11] + 0x6d9d6122, 16);
 MD5STEP(H, b, c, d, a, puiIn[14] + 0xfde5380c, 23);
 MD5STEP(H, a, b, c, d, puiIn[1] + 0xa4beea44, 4);
 MD5STEP(H, d, a, b, c, puiIn[4] + 0x4bdecfa9, 11);
 MD5STEP(H, c, d, a, b, puiIn[7] + 0xf6bb4b60, 16);
 MD5STEP(H, b, c, d, a, puiIn[10] + 0xbebfbc70, 23);
 MD5STEP(H, a, b, c, d, puiIn[13] + 0x289b7ec6, 4);
 MD5STEP(H, d, a, b, c, puiIn[0] + 0xeaa127fa, 11);
 MD5STEP(H, c, d, a, b, puiIn[3] + 0xd4ef3085, 16);
 MD5STEP(H, b, c, d, a, puiIn[6] + 0x04881d05, 23);
 MD5STEP(H, a, b, c, d, puiIn[9] + 0xd9d4d039, 4);
 MD5STEP(H, d, a, b, c, puiIn[12] + 0xe6db99e5, 11);
 MD5STEP(H, c, d, a, b, puiIn[15] + 0x1fa27cf8, 16);
 MD5STEP(H, b, c, d, a, puiIn[2] + 0xc4ac5665, 23);
 //第四轮
 MD5STEP(I, a, b, c, d, puiIn[0] + 0xf4292244, 6);
 MD5STEP(I, d, a, b, c, puiIn[7] + 0x432aff97, 10);
 MD5STEP(I, c, d, a, b, puiIn[14] + 0xab9423a7, 15);
 MD5STEP(I, b, c, d, a, puiIn[5] + 0xfc93a039, 21);
 MD5STEP(I, a, b, c, d, puiIn[12] + 0x655b59c3, 6);
 MD5STEP(I, d, a, b, c, puiIn[3] + 0x8f0ccc92, 10);
 MD5STEP(I, c, d, a, b, puiIn[10] + 0xffeff47d, 15);
 MD5STEP(I, b, c, d, a, puiIn[1] + 0x85845dd1, 21);
 MD5STEP(I, a, b, c, d, puiIn[8] + 0x6fa87e4f, 6);
 MD5STEP(I, d, a, b, c, puiIn[15] + 0xfe2ce6e0, 10);
 MD5STEP(I, c, d, a, b, puiIn[6] + 0xa3014314, 15);
 MD5STEP(I, b, c, d, a, puiIn[13] + 0x4e0811a1, 21);
 MD5STEP(I, a, b, c, d, puiIn[4] + 0xf7537e82, 6);
 MD5STEP(I, d, a, b, c, puiIn[11] + 0xbd3af235, 10);
 MD5STEP(I, c, d, a, b, puiIn[2] + 0x2ad7d2bb, 15);
 MD5STEP(I, b, c, d, a, puiIn[9] + 0xeb86d391, 21);
 //将ABCD分别加上abcd,
 m_auiBuf[0] += a;
 m_auiBuf[1] += b;
 m_auiBuf[2] += c;
 m_auiBuf[3] += d;
}

void CMD5::DigestFile(string const& readFile, char* pcDigest)
{
 //以二进制的形式打开文件中的内容
 ifstream Readin(readFile.c_str(), ios::binary);
 if(!Readin)//打开失败
 {
  ostrstream ostr;
  ostr<<"打开加密文件失败!"<<endl;
 }
 //打开文件成功
 Reset();
 //开始读取文件
 char szLargeBuff[BUFF_LEN+1] = {0};
 char szBuff[DATA_LEN+1] = {0};
 //开始读取数据
 CFileBuffer fileRead(Readin, szLargeBuff, BUFF_LEN, DATA_LEN);
 int iRead;
 //一直读取数据
 while((iRead = fileRead.GetData(szBuff)) > 0)
  AddData(szBuff, iRead);
 //关闭文件
 Readin.close();
 //对文件进行最后一步进行加密
 FinalDigest(pcDigest);
}
2)、RSA:

// RSA.h: interface for the CRSA class.
//
//

#if !defined(AFX_RSA_H__A0CC2413_F410_45CE_911B_7A21D7A5155B__INCL

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 141
    评论
评论 141
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值