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

📄 difcrack.cpp

📁 DES查分攻击源代码
💻 CPP
字号:
// DifCrack.cpp: implementation of the CDifCrack class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "DesDemo.h"
#include "DifCrack.h"
#include "GaussRandom.h"

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


//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDifCrack::CDifCrack()
{
	m_bLogIt = TRUE;
	memset(m_KeyMap,0,8*64*sizeof(int));

	if(m_bLogIt)
		m_logfile = fopen("difcrack.txt","w+");
	else m_logfile = NULL;
}

CDifCrack::~CDifCrack()
{
	if(m_logfile)
		fclose(m_logfile);

	ClearCrackData();
}
void CDifCrack::GetIN(bool *&pResult,int &nLen,const bool B[6],const bool C[4],const int iBox)
{	
	DumpString("开始计算IN集合:",5);
	DumpString("输入B:",5);
	DumpArray(B,6,6,5);
	DumpString("输入C:",5);
	DumpArray(C,4,4,5);

	nLen = 0;
	bool* pAll = NULL;
	int nTotal = 0;
	GetAll(pAll,nTotal);
	

	bool *pTmp = new bool[nTotal*6];
	bool *p1 = pTmp;
	bool *p2 = pAll;
	for(int i = 0;i<nTotal;i++)
	{
		bool s1[4],s2[4],st[6];		
		memcpy(st,p2,6);
		//计算Sj(Bj) XOR Sj(Bj XOR Bj')
		//DumpString("Before Sj(Bj) :",5);
		//DumpArray(st,6,6,5);
		S(s1,st,iBox);
		//DumpString("After Sj(Bj) :",5);
		//DumpArray(s1,4,4,5);
		Xor(st,B,6);
		S(s2,st,iBox);
		Xor(s2,s1,4);
	

		if(IsEqual(s2,C,4))
		{			
			memcpy(p1,st,6);
			p1 +=6;
			nLen ++;
		}
		p2 += 6;
	}
	nLen = nLen*6;
	pResult = new bool[nLen];
	memcpy(pResult,pTmp,nLen);
	delete[] pTmp;
	delete[] pAll;
	DumpString("输出IN集合:",5);
	DumpArray(pResult,nLen,6,5);
	DumpString("结束IN集合的计算:",5);
}
//计算Testj(Ej,Ej*,Cj') = {Bj XOR Ej|Bj is in INj(Ej',Cj')}
void CDifCrack::GetTEST(bool* &pResult,int &nLen,const bool E1[6],const bool E2[6],const bool C[4],const int iBox)
{
	DumpString("算TEST集合:",4);
	DumpString("输入E:",4);
	DumpArray(E1,6,6,4);
	DumpString("输入E(*):",4);
	DumpArray(E2,6,6,4);
	DumpString("输入C:",4);
	DumpArray(C,4,4,4);
	
	bool E[6];
	memcpy(E,E1,6);
	Xor(E,E2,6);

//	DumpString("\n XOR E2:");
//	DumpArray(E,6,6);

	GetIN(pResult,nLen,E,C,iBox);

	bool* p = pResult;
	for(int i = 0;i<nLen/6;i++)
	{
		Xor(p,E1,6);
		p+=6;
	}
	DumpString("输出TEST集合:",4);
	DumpArray(pResult,nLen,6,4);
	DumpString("结束计算TEST集合:",4);

}

void CDifCrack::GetAll(bool* &bResult,int &nLen,int nBit)
{
	nLen = 1<<nBit;
	bResult  = new bool[nLen*nBit];
	memset(bResult,0,nLen*nBit);
	bool* pData = bResult;
	for(int i = 0;i<nLen;i++)
	{
		for(int j = 0;j<nBit;j++)
		{
			pData[j] |= (j==0)?(i & 1):((i>>j) & 1);
		}
		pData+=nBit;		
	}
}


bool CDifCrack::IsEqual(const bool* p1,const bool* p2,int len)
{
	bool bE = true;
	for(int i = 0;i<len;i++)
	{
		if(p1[i]!=p2[i])
		{
			bE = false;
			break;
		}
	}
	return bE;
}

void CDifCrack::Xor(bool* pDest,const bool* pSrc,int len)
{
	for(int i = 0;i<len;i++)
	{
		pDest[i] ^= pSrc[i];
	}
}

void CDifCrack::S(bool pDest[4],bool pSrc[6],int iBox)
{
	bool *p1 = pSrc;
	bool *p2 = pDest;
	//代换/选择(S-Box)
	//int j = (p1[0]<<1) + p1[5];
	//int k = (p1[1]<<3) + (p1[2]<<2) + (p1[3]<<1) + p1[4];
	int j = (p1[5]<<1) + p1[0];
	int k = (p1[4]<<3) + (p1[3]<<2) + (p1[2]<<1) + p1[1];
	ByteToBit(p2, &SBOXTable[iBox][j][k],4);	
}

void CDifCrack::ByteToBit(bool *Out, const char *In, int bits)
{
	for(int i=0; i<bits; ++i)
		Out[i] = (In[i>>3]>>(i&7)) & 1;
}
void CDifCrack::BitToByte(char *Out, const bool *In, int bits)
{
	memset(Out, 0, bits>>3);
	for(int i=0; i<bits; ++i)
		Out[i>>3] |= In[i]<<(i&7);
}
//扩充置换
void CDifCrack::Expansion(bool bDest[48],const bool bSrc[32])
{	
	for(int i = 0;i<48;i++)
	{
		bDest[i] = bSrc[ETable[i/6][i%6]-1];
	}
}
void CDifCrack::AddData(char* p1,char* p2,char* c1,char* c2,int nLen)
{
	CRACKDATA* pCrackData = new CRACKDATA;
	ByteToBit(pCrackData->plaintext1,p1,64);
	ByteToBit(pCrackData->plaintext2,p2,64);
	ByteToBit(pCrackData->cryptograph1,c1,64);
	ByteToBit(pCrackData->cryptograph2,c2,64);

	m_CrackData.Add(pCrackData);
}
void CDifCrack::PInvert(bool bDest[32],bool bSrc[32])
{
	for(int i = 0;i<32;i++)
	{		
		bDest[i] = bSrc[PInvertTable[i/4][i%4]-1];
	}
}
bool CDifCrack::CrackIt()
{
	if(m_CrackData.GetSize()==0)
		return false;

	DumpString("开始攻击",0);
	for(int i = 0;i<m_CrackData.GetSize();i++)
	{
		bool E1[48],E2[48],C[32];
		CRACKDATA* pCrackData = m_CrackData.GetAt(i);

		bool bCry1[64];
		bool bCry2[64];
		bool bPlain1[64];
		bool bPlain2[64];

		DumpString("第 %d 对明密文攻击\n",i,1);

		DumpString("nL0R0:",1);		
		DumpArray(pCrackData->plaintext1,64,8,1);
		DumpString("L0(*)R0(*):",1);		
		DumpArray(pCrackData->plaintext2,64,8,1);
		DumpString("L3R3:",1);		
		DumpArray(pCrackData->cryptograph1,64,8,1);
		DumpString("L3(*)R3(*):",1);
		DumpArray(pCrackData->cryptograph2,64,8,1);

		IP(bCry1,pCrackData->cryptograph1);
		IP(bCry2,pCrackData->cryptograph2);

		IP(bPlain1,pCrackData->plaintext1);
		IP(bPlain2,pCrackData->plaintext2);

		Expansion(E1,bCry1);
		Expansion(E2,bCry2);

		//DumpString("\nE1:\n");
		//DumpArray(E1,48,8);
		//DumpString("\nE2:\n");
		//DumpArray(E2,48,8);

		bool _R3[32],_L0[32];
		//计算R3'
		memcpy(_R3,&bCry1[32],32);
		Xor(_R3,&bCry2[32],32);

		//DumpString("\n_R3:\n");
		//DumpArray(_R3,32,8);	

		//计算L0'
		memcpy(_L0,bPlain1,32);
		Xor(_L0,bPlain2,32);

		//DumpString("\n_L0:\n");
		//DumpArray(_L0,32,8);

		//R3' XOR L0'
		bool bTmp[32];
		memcpy(bTmp,_R3,32);
		Xor(bTmp,_L0,32);

		//DumpString("\nR3' XOR L0':\n");
		//DumpArray(bTmp,32,8);

		//P^-1,计算C'
		PInvert(C,bTmp);

		DumpString("开始分别攻击8个S盒\n",2);
		//分别攻击8个S盒	
		for(int j = 0;j<8;j++)
		{		
			DumpString("开始攻击第%d个S盒\n",j,3);
			bool* pTest = NULL; 
			int   nLen = 0;
			GetTEST(pTest,nLen,E1+j*6,E2+j*6,C+j*4,j);
			for(int k = 0;k<nLen/6;k++)
			{			
				char ch = 0x0;
				BitToByte(&ch,pTest + 6*k,6);
				m_KeyMap[j][ch]++;
			}
			DumpString("KeyMap:\n",3);
			DumpArray(m_KeyMap[j],64,8,3);

			DumpString("结束攻击第%d个S盒\n",j,3);

			delete pTest;
		}
		DumpString("结束攻击8个S盒\n",2);
	}
	DumpString("结束攻击\n",0);
	return true;
}



void CDifCrack::GetKey(bool bKey[48],int &nLen)
{
	for(int i = 0;i<8;i++)
	{
		char nMaxPos = 0;
		char nMaxV = 0;
		for(int j = 0 ;j<64;j++)
		{
			if(m_KeyMap[i][j]>nMaxV)
			{
				nMaxPos = j;
				nMaxV = m_KeyMap[i][j];
			}
		}

		ByteToBit(bKey + i*6,&nMaxPos,6);
	}	
	nLen = 48;
}
bool CDifCrack::GetKey(char bKey[8],int &nKeyLen,int nRound)
{
	bool bKeyLast[48];
	bool bKey2[56];
	bool bKey0[64];
	int nLen;
	GetKey(bKeyLast,nLen);

	DumpString("最后一轮密码:\n",0);
	DumpArray(bKeyLast,48,6,0);

	PC2Invert(bKey2,bKeyLast);
	bool bRet = GetNext8BitKey(bKey2,bKeyLast,nRound);		
	if(bRet == false)
		return false;

	DumpString("所有密码:\n",0);
	DumpArray(bKey2,56,8,0);

	for(int i = nRound -1;i>=0;i--)
	{		
		RotateR(bKey2,28,I_ShiftTable[i]);
		RotateR(bKey2+28,28,I_ShiftTable[i]);
	}

	PC1Invert(bKey0,bKey2);

	DumpString("CrackKey:\n",0);
	DumpArray(bKey0,64,8,0);
	BitToByte(bKey,bKey0,64);

	return true;
}

void CDifCrack::RotateR(bool *In, int len, int loop)
{
	bool *bTmp = new bool[len]; 
	memcpy(bTmp,In,len);
	memcpy(In+loop, bTmp, len-loop);
	memcpy(In, bTmp+len-loop, loop);	
	delete[] bTmp;

}

//初始置换
void CDifCrack::IP(bool bDest[64],const bool bSrc[64])
{	
	for(int i = 0;i<64;i++)
	{		
		bDest[i] = bSrc[i];//[IPTable[i/8][i%8]-1];
		//bDest[i] = bSrc[IPTable[i/8][i%8]-1];
	}	
}
void CDifCrack::IPInvert(bool bDest[64],const bool bSrc[64])
{		
	for(int i = 0;i<64;i++)
	{		
		bDest[i] = bSrc[i];///[IPInvertTable[i/8][i%8]-1];
		//bDest[i] = bSrc[IPInvertTable[i/8][i%8]-1];
	}	
}
void CDifCrack::GenerateCrackData(DWORD nPair,char *pKey,int nKeyLen)
{
	FILE* file;
	file = fopen("crackdata.dat","w+");	
	CDes des;
	for(DWORD d = 0;d<nPair;d++)
	{		
		char p1[8];
		char p2[8];
		char c1[8];
		char c2[8];

		//Random(256,p1,8);
		CGaussRandom rand;
		for(int i = 0;i<8;i++)
		{
			p1[i] = rand.Random(0,256);
		}
		memcpy(p2+4,p1+4,4);

		//Random(256,p2,4);
		for(int j = 0;j<4;j++)
		{
			p2[j] = rand.Random(0,256);
		}//*/
		des.Encrypt(c1,p1,8,pKey,nKeyLen);		
		des.Encrypt(c2,p2,8,pKey,nKeyLen);
		fwrite(p1,sizeof(char), 8,file);
		fwrite(p2,sizeof(char), 8,file);
		fwrite(c1,sizeof(char), 8,file);
		fwrite(c2,sizeof(char), 8,file);
	}
	fclose(file);
}

bool CDifCrack::ReadCrackData(DWORD nPair)
{
	ClearCrackData();
	static long fPos = 0;
	FILE *file = NULL;
	try
	{		
		file = fopen("crackdata.dat","r");	

		if(nPair == 0)
		{
			while(!feof(file))
			{				
				char data[32];
				unsigned int nRead = fread(data,sizeof(char),32,file);		

				AddData(data,data+8,data+16,data+24,8);		
			}
		}
		else 
		{
			int nReadItem = 0;
			while(!feof(file))
			{
				char data[32];
				unsigned int nRead = fread(data,sizeof(char),32,file);
				
				AddData(data,data+8,data+16,data+24,8);		
				nReadItem ++ ;
				if(nReadItem>=(int)nPair)
					break;
			}
		}
		fclose(file);
	}
	catch(char* pE)
	{
		if(file!= NULL)
			fclose(file);
		AfxMessageBox(pE);
		return false;
	}	
	return true;
}
void CDifCrack::ClearCrackData()
{
	for(int i = 0;i<m_CrackData.GetSize();i++)
	{
		CRACKDATA* pCrackData = m_CrackData.GetAt(i);
		delete pCrackData;
	}
	m_CrackData.RemoveAll();
}


void CDifCrack::PC2Invert(bool bDest[56],const bool bSrc[48])
{
	memset(bDest,0xFF,56);

	for(int i = 0;i<56;i++)
	{
		bDest[i] = bSrc[PC2InvertTable[i/8][i%8]-1];
	}

}
void CDifCrack::PC2(bool bDest[48],const bool bSrc[56])
{
	for(int i = 0;i<48;i++)
	{
		bDest[i] = bSrc[PC2Table[i/8][i%8]-1];
	}
}

void CDifCrack::PC1Invert(bool bDest[64],const bool bSrc[56])
{
	memset(bDest,0,64);
	for(int i = 0;i<64;i++)
	{
		bDest[i] = bSrc[PC1InvertTable[i/8][i%8]-1];
	}
}

bool CDifCrack::GetNext8BitKey(bool bKey[56],bool bKeyLast[48],int nRound)
{
	bool* bAll = NULL;
	int nLen = 0;
	GetAll(bAll,nLen,8);	
	ASSERT(nLen == 256);

	int nPos[8];
	int nCount = 0;
	for(int i = 0;i<56;i++)
	{
		if(bKey[i] == 0xFF)
		{
			nPos[nCount++] = i;
			//if(nCount == 8)
			//	break;
		}
	}
	ASSERT(nCount == 8);

	bool bGetIt = false;
    bool* p = bAll;

	CDes des(nRound);	
	bool bTmpKey[56];
	bool bCrackKey[64];
	bool bCrypto[64];
	for(int j = 0;j<256;j++)
	{
		for(int k = 0;k<8;k++)
		{
			bKey[nPos[k]] = p[k];
		}

		memcpy(bTmpKey,bKey,56);
		for(int i = nRound -1;i>=0;i--)
		{		
			RotateR(bTmpKey,28,I_ShiftTable[i]);
			RotateR(bTmpKey+28,28,I_ShiftTable[i]);
		}
		
		PC1Invert(bCrackKey,bTmpKey);
			
		bGetIt = true;
		for(int h = 0;h<3;h++)
		{
			if(m_CrackData.GetSize()<= h)
				break;
			CRACKDATA* pData = m_CrackData.GetAt(h);			
			des.Encrypt(bCrypto,pData->plaintext1,bCrackKey);
			if(IsEqual(bCrypto,pData->cryptograph1,64) == false)
			{
				bGetIt = false;
				/*DumpString("bCrypto:",0);
				
				DumpArray(bCrypto,64,8,0);
				DumpString("Org:",0);
				DumpArray(pData->cryptograph1,64,8,0);		*/		
				break;
			}			
		}
		if(bGetIt)
			break;
		p+=8;
	}
	delete[] bAll;

	return bGetIt;
}


void CDifCrack::DumpString(CString str,int nIndent)
{
	if(m_bLogIt == FALSE)
		return ;

	CString strLog = "\n";
	for(int _j = 0;_j<nIndent;_j++)
	    strLog +="	";
	strLog += str;
	fwrite(strLog,sizeof(char),strLog.GetLength(),m_logfile);	
}

void CDifCrack::DumpString(CString str,int n,int nIndent)
{	
	if(m_bLogIt == FALSE)
		return ;

	CString strLog;
	strLog.Format(str,n);
	CString strTmp;
	for(int _j = 0;_j<nIndent;_j++)
	    strTmp += "	";
	strLog = "\n"+strTmp + strLog;
    fwrite(strLog,sizeof(char),strLog.GetLength(),m_logfile);
}

void CDifCrack::DumpArray(const bool array[],int nLength,int nLine,int nIndent)
{
	if(m_bLogIt == FALSE)
		return ;

	CString strLog,strTmp;

	for(int _i = 0;_i< nLength; _i++)
	{
		if(_i%(nLine*4) == 0)
			strLog+="\n";
		if(_i%nLine == 0)
		{
			strLog+="\n";
			for(int _j = 0;_j<nIndent;_j++)
				strLog +="	";
		}		
		strTmp.Format("%d ",array[_i]);
		strLog+=strTmp;				
	}
	fwrite(strLog,sizeof(char),strLog.GetLength(),m_logfile);
}
void CDifCrack::DumpArray(const int array[],int nLength,int nLine,int nIndent)
{
	if(m_bLogIt == FALSE)
		return ;

	CString strLog;
	for(int _i = 0;_i< nLength; _i++)
	{
		if(_i%(nLine*4) == 0)
			strLog+="\n";
		if(_i%nLine == 0)
		{
			strLog+="\n";
			for(int _j = 0;_j<nIndent;_j++)
				strLog +="	";
		}
		CString strTmp;
		strTmp.Format("%d ",array[_i]);
		strLog+=strTmp;		
	}
	fwrite(strLog,sizeof(char),strLog.GetLength(),m_logfile);		
}

void CDifCrack::LogIt(BOOL bLog)
{
	m_bLogIt = bLog;
	if(m_bLogIt)
	{
		if(m_logfile == NULL)
			m_logfile = fopen("difcrack.txt","w+");
	}
	else 
	{		
		if(m_logfile != NULL)
			fclose(m_logfile);
		m_logfile = NULL;
	}
}

⌨️ 快捷键说明

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