📄 difcrack.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 + -