⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 desdlg.cpp

📁 包涵了密码学教程里面的大部分加密算法
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// DesDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Crypt.h"
#include "DesDlg.h"
//#include "DES.h"

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


//相关的变量
char  plaintext[1000];			//填充后的明文
CString  plaintext_0;			//原始明文
BOOL  bj = TRUE;
char  cryptography_ECB[1000];	//ECB密文
char  cryptography_CBC[1000];	//CBC密文
char  cryptography_CFB[1000];	//CFB密文
char  cryptography_OFB[1000];	//OFB密文

char  Key_64[8];				//初始的64 bit密钥
char  Key_56[7];				//64 bit到56 bit密钥
char  Key[17][6];				//16次运算的子密钥
char  IV[8];					//初始随机向量
int   len, LL;					//原始明文的长度和填充后的长度

//密钥初始交换数组
int   PC_1[56] = {57, 49, 41, 33, 25, 17, 9,
					1, 58, 50, 42, 34, 26, 18,
					10, 2, 59, 51, 43, 35, 27,
					19, 11, 3, 60, 52, 44, 36,
					63, 55, 47, 39, 31, 23, 15,
					7, 62, 54, 46, 38, 30, 22,
					14, 6, 61, 53, 45, 37, 29,
					21, 13, 5, 28, 20, 12, 4};

//用于密钥的56 bit输入48 bit输出
int PC_2[48] = {14, 17, 11, 24, 1, 5,
					3, 28, 15, 6, 21, 10,
					23, 19, 12, 4, 26, 8,
					16, 7, 27, 20, 13, 2,
					41, 52, 31, 37, 47, 55,
					30, 40, 51, 45, 33, 48,
					44, 49, 39, 56, 34, 53,
					46, 42, 50, 36, 29, 32};
//用于明文的初始置换
int ip_1[64] = {58, 50, 42, 34, 26, 18, 10, 2,
				60, 52, 44, 36, 28, 20, 12, 4,
				62, 54, 46, 38, 30, 22, 14, 6,
				64, 56, 48, 40, 32, 24, 16, 8,
				57, 49, 41, 33, 25, 17, 9, 1,
				59, 51, 43, 35, 27, 19, 11, 3,
				61, 53, 45, 37, 29, 21, 13, 5,
				63, 55, 47, 39, 31, 23, 15, 7};

//用于明文的逆初始置换
int ip_2[64] = {40, 8, 48, 16, 56, 24, 64, 32,
				39, 7, 47, 15, 55, 23, 63, 31,
				38, 6, 46, 14, 54, 22, 62, 30,
				37, 5, 45, 13, 53, 21, 61, 29,
				36, 4, 44, 12, 52, 20, 60, 28,
				35, 3, 43, 11, 51, 19, 59, 27,
				34, 2, 42, 10, 50, 18, 58, 26,
				33, 1, 41, 9,  49, 17, 57, 25};

//用于32 bit的明文扩充为48 bit用于复杂函数
int E_P[48] = {32, 1, 2, 3, 4, 5,
				4, 5, 6, 7, 8, 9,
				8, 9, 10, 11, 12, 13,
				12, 13, 14, 15, 16, 17,
				16, 17, 18, 19, 20, 21,
				20, 21, 22, 23, 24, 25,
				24, 25, 26, 27, 28, 29,
				28, 29, 30, 31, 32, 1};

//用于与ki作用后的32 bit置换
int P[32] = {16, 7, 20, 21,
				29, 12, 28, 17,
				1, 15, 23, 26,
				5, 18, 31, 10,
				2, 8, 24, 14,
				32, 27, 3, 9,
				19, 13, 30, 6,
				22, 11, 4, 25};
//8个S盒数据
int S_box[9][64] = {
	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
		0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
	{14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
		0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
		4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
		15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13},
	{15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,
		3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,
		0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,
		13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9},
	{10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,
		13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,
		13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,
		1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12},
	{7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,
		13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,
		10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,
		3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14},
	{2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,
		14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,
		4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,
		11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3},
	{12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,
		10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,
		9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,
		4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13},
	{4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,
		13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,
		1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,
		6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12},
	{13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,
		1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,
		7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,
		2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11},
};

//移位数组
int Ls[17] = {0,1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};


/////////////////////////////////////////////////////////////////////////////
// CDesDlg dialog

CDesDlg::CDesDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CDesDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CDesDlg)
	m_strPlainText = _T("");
	m_strBKey = _T("");
	m_strBPlainText = _T("");
	m_strCBCCipher = _T("");
	m_strCFBCipher = _T("");
	m_strECBCipher = _T("");
	m_strInitVector = _T("");
	m_strOFBCipher = _T("");
	m_iNum = 0;
	m_strKey = _T("");
	//}}AFX_DATA_INIT
}


void CDesDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CDesDlg)
	DDX_Text(pDX, IDC_PlainText, m_strPlainText);
	DDX_Text(pDX, IDC_BKey, m_strBKey);
	DDX_Text(pDX, IDC_BPlainText, m_strBPlainText);
	DDX_Text(pDX, IDC_CBCCipher, m_strCBCCipher);
	DDX_Text(pDX, IDC_CFBCipher, m_strCFBCipher);
	DDX_Text(pDX, IDC_ECBCipher, m_strECBCipher);
	DDX_Text(pDX, IDC_InitVector, m_strInitVector);
	DDX_Text(pDX, IDC_OFBCipher, m_strOFBCipher);
	DDX_Text(pDX, IDC_Num, m_iNum);
	DDX_Text(pDX, IDC_Key, m_strKey);
	DDV_MaxChars(pDX, m_strKey, 8);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CDesDlg, CDialog)
	//{{AFX_MSG_MAP(CDesDlg)
	ON_BN_CLICKED(IDC_Encrypt, OnDESEncrypt)
	ON_BN_CLICKED(IDC_ECBDecrypt, OnECBDecrypt)
	ON_BN_CLICKED(IDC_CBCDecrypt, OnCBCDecrypt)
	ON_BN_CLICKED(IDC_CFBDecrypt, OnCFBDecrypt)
	ON_BN_CLICKED(IDC_OFBDecrypt, OnOFBDecrypt)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CDesDlg message handlers


//---------------------------------DES加密算法---------------------------------------
/*
  1. 得到明文字符串;
  2. 将明文字符串分组;
  3. 对每组明文进行加密;
*/
void CDesDlg::OnDESEncrypt() 
{
	// TODO: Add your control notification handler code here
	bj = TRUE;
	Create_Key();
	if(!bj)  return;
	Create_IV();
	Encrypt();
}
//-----------------------------------------------------------------------------------


//选择字符ch的第n(1--8)位二进制数据
BOOL CDesDlg::pick(char ch, int n)
{
	return(ch & char(1)<<(8-n));
}


BOOL CDesDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
	// TODO: Add extra initialization here
	
	//限定编辑框只能输入字母
	//m_wndEdit.SubclassDlgItem(IDC_PlainText, this);

	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}


//实现IP置换,*p是置换数组,*C是要交换的字符串,n是要交换的bit总数
void CDesDlg::IP(int *p, int n, char *C)
{
	int i, nn;
	
	if(n/8*8 == n)
		nn = n/8;
	else
		nn = n/8 + 1;

	char *temp = new char[nn];
	for(i=0; i<nn; i++)
		temp[i] = char(0);

	for(i=0; i<n; i++)
	{
		int t1 = (p[i]-1)/8;
		int t2 = (p[i]-1)%8 + 1;
		int j  = i%8 + 1;
		if(pick(C[t1], t2))
			temp[i/8] = (temp[i/8])|(char(1)<<(8-j));
	}

	for(i=0; i<nn; i++)
		C[i] = temp[i];
	delete temp;
}


//对字符串C进行循环左移k位, n是总长
void CDesDlg::LS(int k, int n, char *C)
{
	int i;
	int *p = new int[n];
	//先构造置换数组
	for(i=0; i<n; i++)
		p[i] = (i+k)%n + 1;
	//利用IP移位
	IP(p, n, C);
	delete p;
}


//生成密钥
void CDesDlg::Create_Key()
{
	CString key0;
	GetDlgItemText(IDC_Key, key0);
	int i;
	if(key0.GetLength() != 8)
	{
		MessageBox("请输入8 Byte密码!", "error!", MB_ICONHAND);
		bj = FALSE;
		return;
	}

	char *laa = new char[8*8 + 8];
	int h = 0;
	for(i=0; i<8; i++)
	{
		for(int j=1; j<=8; j++)
		{
			if(pick(key0.GetAt(i), j))
				laa[h++] = '1';
			else
				laa[h++] = '0';
		}
		laa[h++] = ' ';
	}
	laa[h] = '\0';
	SetDlgItemText(IDC_BKey, laa);

	char L[4], R[4];
	for(i=0; i<4; i++)
	{
		L[i] = char(0);
		R[i] = char(0);
	}
	for(i=0; i<8; i++)
		Key_64[i] = key0.GetAt(i);
	IP(PC_1, 56, Key_56, Key_64);
	
	int p1[28], p2[28];
	for(i=0; i<28; i++)
	{
		p1[i] = i+1;
		p2[i] = i+29;
	}
	
	IP(p1,28,L,Key_56);
	IP(p2,28,R,Key_56);

	for(i=1; i<=16; i++)
	{
		LS(Ls[i], 28, L);
		LS(Ls[i], 28, R);
		char temp[7];
		for(int j=0; j<7; j++)
			temp[j] = char(0);
		Combination(L,28,R,28,temp);
		for(j=0; j<6; j++)
			Key[i][j] = char(0);
		IP(PC_2, 48, Key[i], temp);
	}
}


//用于压缩和扩充的IP置换,从c1中读取数据,使得C的数据得到改变(根据p指引)
void CDesDlg::IP(int *p, int n, char *C, char *c1)
{
	int i;
	int nn;

	if(n/8*8 == n) 
		nn = n/8;
	else
		nn = n/8 + 1;
	char *temp1 = new char[nn];
	for(i=0; i<nn; i++)
		temp1[i] = char(0);

	for(i=0; i<n; i++)
	{
		int t1 = (p[i]-1)/8;
		int t2 = (p[i]-1)%8 + 1;
		int j = i%8 + 1;
		if(pick(c1[t1], t2))
			temp1[i/8] = (temp1[i/8]) | (char(1)<<(8-j));
	}

	for(i=0; i<nn; i++)
		C[i] = temp1[i];

	delete temp1;
}


//合并c1,c2到C, n1和n2为c1和c2的长度
void CDesDlg::Combination(char *c1, int n1, char *c2, int n2, char *C)
{
	int i;
	for(i=0; i<(n1+n2)/8+1; i++)
		C[i] = char(0);
	for(i=0; i<n1; i++)
	{
		int t1 = i/8;
		int t2 = i%8 + 1;
		if(pick(c1[t1], t2))
			C[i/8] = (C[i/8])|(char(1)<<(8-t2));
	}

	for(i=n1; i<n1+n2; i++)
	{
		int t1 = (i-n1)/8;
		int t2 = (i-n1)%8 + 1;
		if(pick(c2[t1], t2))
			C[i/8] = (C[i/8])|(char(1)<<(8-((i%8)+1)));
	}
}


//-------------------------------------------------------------//
//加密部分
void CDesDlg::Encrypt()
{
	//用于存放密文区块
	int k = 0;
	int i, j;

	//用于每次取出64 bit字符进行运算
	char p[8];
	//用于保存每个加密区块的结果
	char q[8];
	//加密的序号
	int index = 0;
	
	GetDlgItemText(IDC_PlainText, plaintext_0);
	len = plaintext_0.GetLength();
	
	//在明文框显示明文字符数
	SetDlgItemInt(IDC_Num, len, TRUE);

	if(len%8 != 0) 
		LL = len+8-len%8;
	else
		LL = len;
	
	for(i=0; i<len; i++)
		plaintext[i] = plaintext_0.GetAt(i);	
	for(i=len; i<LL; i++)
		plaintext[i] = '#';

	//显示二进制明文
	char *la = new char[LL*8+LL];
	int h = 0;
	for(i=0; i<LL; i++)
	{
		for(j=1; j<=8; j++)
		{
			if(pick(plaintext[i],j))
				la[h++] = '1';
			else
				la[h++] = '0';
		}
		la[h++] = ' ';
	}
	//设置结束符标志
	la[h] = '\0';
	SetDlgItemText(IDC_BPlainText, la);

	//-----------------------ECB加密算法----------------------//
	for(i=0; i<LL; i+=8)
	{
		//每次取64 bit(8个字符)进行运算
		for(j=0; j<8; j++)
			p[j] = plaintext[i+j];
		//初始的IP置换
		IP(ip_1, 64, p);
		char L[4], R[4];
		for(k=0; k<4; k++)
		{
			L[k] = p[k];
			R[k] = p[4+k];
		}

		for(j=1; j<=16; j++)
		{
			Fk(L, R, j);
			InterChange(L, R, 4);
		}
		
		for(j=0; j<4; j++)
		{
			p[j] = L[j];
			p[j+4] = R[j];
		}

		//逆初始置换
		IP(ip_2, 64, p);
		for(j=0; j<8; j++)
			cryptography_ECB[i+j] = p[j];
	}

	//-------------显示ECB二进制密文----------------//
	char *code_ecb = new char[LL*8 + LL];
	h = 0;
	for(i=0; i<LL; i++)
	{
		for(j=1; j<=8; j++)
		{
			if(pick(cryptography_ECB[i], j))
				code_ecb[h++] = '1';
			else
				code_ecb[h++] = '0';
		}
		code_ecb[h++] = ' ';
	}
	code_ecb[h] = '\0';
	plaintext[LL] = '\0';
	cryptography_ECB[LL] = '\0';
	SetDlgItemText(IDC_ECBCipher, code_ecb);
	//---------------------ECB加密结束--------------------------//

	//------------------------CBC加密算法-----------------------//
	for(i=0; i<LL; i+=8)
	{
		for(j=0; j<8; j++)
			p[j] = plaintext[i+j];
		
		if(index == 0)
		{
			for(j=0; j<8; j++)
				p[j] = p[j] ^ IV[j];
		}
		else
		{
			for(j=0; j<8; j++)
				p[j] = p[j] ^ q[j];
		}

		IP(ip_1, 64, p);
		char L[4], R[4];
		for(k=0; k<4; k++)
		{
			L[k] = p[k];
			R[k] = p[4+k];
		}
		for(j=1; j<=16; j++)
		{
			Fk(L, R, j);
			InterChange(L, R, 4);
		}
		for(k=0; k<4; k++)
		{
			q[k] = L[k];
			q[k+4] = R[k];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -