在实习即将结束之前,还有几天空闲,遂完成DES算法,在实现过程中发现调试代码正确性非常繁琐,我是动手算出来比对的。这里我把代码写出来供别人参考,欢迎对我的不足之处给点意见。共同提高。
DES算法由加密、解密和子密钥的生成三部分组成。
DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64 (mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。
加密过程主要涉及 明文串的IP置换,F函数,子密钥的生成,SBox置换,IP逆置换。
DES算法密钥有效位是56位,即用56位的密钥来加密64位的数据。加密期间56位密钥要扩展成64位的密钥,加入奇偶效验位。我想主要是用来传输密钥用的吧,怕传输过程中出错。当然传输过程中还得对密钥加密(一般使用非对称加密)。
uchar VerifyOddEven(uchar x)
{
unsigned int n;
uchar ucTemp =x;
x >>= 1;
for(n=0; x; n++)
{
x &= x-1;
}
if (n%2 == 0)
{
if (!(ucTemp & 1))
{
ucTemp += 1;
}
}
return ucTemp;
}
void ChgKey56To64(uchar *pszKey,uchar *pszKeyOut)
{
uchar ucSave = 0;
uchar ucTemp,ucFill;
for (int i=0; i<8; i++)
{
ucTemp = pszKey[i]>>i;
ucFill = ucSave + ucTemp;
pszKeyOut[i] = VerifyOddEven(ucFill);
ucSave = pszKey[i]<<(7-i);
}
}
实现该算法,我采用的数据类型是UNSIGNED LONG ,写得比较繁琐,应该使用CHAR数组的。故我又写了一些函数来测试使用(将数据以十六进制的格式输出)。
void DispHex(uchar ucData)
{
uchar ucTemp;
uchar ucDisp;
ucTemp = ucData&240;
ucTemp = ucTemp >> 4;
if (ucTemp <10)
{
ucDisp = ucTemp+'0';
cout<<ucDisp;
}
else
{
ucDisp = ucTemp+55;
cout<<ucDisp;
}
ucTemp = ucData&15;
if (ucTemp <10)
{
ucDisp = ucTemp+'0';
cout<<ucDisp;
}
else
{
ucDisp = ucTemp+55;
cout<<ucDisp;
}
}
void DispHexBySz(uchar *pszString)
{
int i;
for(i=0; i<strlen((char *)pszString); i++)
{
DispHex(pszString[i]);
}
cout<<endl;
}
void DispHexByUl(ulong ulData)
{
int i;
ulong ulTemp;
uchar ucTemp;
for(i=0; i<4; i++)
{
ulTemp = ulData>>((3-i)*8);
ucTemp = ulTemp & 0x000000FF;
DispHex(ucTemp);
}
cout<<endl;
}
接下来就是置换算法了,我写了一个专门的置换函数REPLACECORE();可用此来进行64至56,64To64,56To48的置换。
void Replace64To64(ulong ulDataL,ulong ulDataR,ulong *ulDataOutL,ulong *ulDataOutR,int Array[],int nArrLen,int core)
{
ReplaceCore(ulDataL,ulDataR,ulDataOutL,ulDataOutR,Array,nArrLen,core,0,0x80000000);
}
void Replace64To56(ulong ulDataL,ulong ulDataR,ulong *ulDataOutL,ulong *ulDataOutR,int Array[],int nArrLen,int core)
{
ReplaceCore(ulDataL,ulDataR,ulDataOutL,ulDataOutR,Array,nArrLen,core,4,0x80000000);
}
void Replace56To48(ulong ulDataL,ulong ulDataR,ulong *ulDataOutL,ulong *ulDataOutR,int Array[],int nArrLen,int core)
{
ReplaceCore(ulDataL,ulDataR,ulDataOutL,ulDataOutR,Array,nArrLen,core,8,0x80000000);
}
void ReplaceCore(ulong ulDataL,ulong ulDataR,ulong *ulDataOutL,ulong *ulDataOutR,int Array[],int nArrLen,int core,int move,ulong ulComTran)
{
int i;
ulong ulTemp;
ulong ulCompute = ulComTran;
int nLocation;
*ulDataOutL = 0;
*ulDataOutR = 0;
for (i=0; i<nArrLen/2; i++)
{
if (Array[i] > core)
{
nLocation = Array[i]-core-1;
ulCompute >>= nLocation;
ulTemp = ulDataR;
ulTemp &= ulCompute;
if (nLocation>=i)
{
ulTemp <<= (nLocation-i);
}
DES算法由加密、解密和子密钥的生成三部分组成。
DES算法处理的数据对象是一组64比特的明文串。设该明文串为m=m1m2…m64 (mi=0或1)。明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。
加密过程主要涉及 明文串的IP置换,F函数,子密钥的生成,SBox置换,IP逆置换。
DES算法密钥有效位是56位,即用56位的密钥来加密64位的数据。加密期间56位密钥要扩展成64位的密钥,加入奇偶效验位。我想主要是用来传输密钥用的吧,怕传输过程中出错。当然传输过程中还得对密钥加密(一般使用非对称加密)。
uchar VerifyOddEven(uchar x)
{
unsigned int n;
uchar ucTemp =x;
x >>= 1;
for(n=0; x; n++)
{
x &= x-1;
}
if (n%2 == 0)
{
if (!(ucTemp & 1))
{
ucTemp += 1;
}
}
return ucTemp;
}
void ChgKey56To64(uchar *pszKey,uchar *pszKeyOut)
{
uchar ucSave = 0;
uchar ucTemp,ucFill;
for (int i=0; i<8; i++)
{
ucTemp = pszKey[i]>>i;
ucFill = ucSave + ucTemp;
pszKeyOut[i] = VerifyOddEven(ucFill);
ucSave = pszKey[i]<<(7-i);
}
}
实现该算法,我采用的数据类型是UNSIGNED LONG ,写得比较繁琐,应该使用CHAR数组的。故我又写了一些函数来测试使用(将数据以十六进制的格式输出)。
void DispHex(uchar ucData)
{
uchar ucTemp;
uchar ucDisp;
ucTemp = ucData&240;
ucTemp = ucTemp >> 4;
if (ucTemp <10)
{
ucDisp = ucTemp+'0';
cout<<ucDisp;
}
else
{
ucDisp = ucTemp+55;
cout<<ucDisp;
}
ucTemp = ucData&15;
if (ucTemp <10)
{
ucDisp = ucTemp+'0';
cout<<ucDisp;
}
else
{
ucDisp = ucTemp+55;
cout<<ucDisp;
}
}
void DispHexBySz(uchar *pszString)
{
int i;
for(i=0; i<strlen((char *)pszString); i++)
{
DispHex(pszString[i]);
}
cout<<endl;
}
void DispHexByUl(ulong ulData)
{
int i;
ulong ulTemp;
uchar ucTemp;
for(i=0; i<4; i++)
{
ulTemp = ulData>>((3-i)*8);
ucTemp = ulTemp & 0x000000FF;
DispHex(ucTemp);
}
cout<<endl;
}
接下来就是置换算法了,我写了一个专门的置换函数REPLACECORE();可用此来进行64至56,64To64,56To48的置换。
void Replace64To64(ulong ulDataL,ulong ulDataR,ulong *ulDataOutL,ulong *ulDataOutR,int Array[],int nArrLen,int core)
{
ReplaceCore(ulDataL,ulDataR,ulDataOutL,ulDataOutR,Array,nArrLen,core,0,0x80000000);
}
void Replace64To56(ulong ulDataL,ulong ulDataR,ulong *ulDataOutL,ulong *ulDataOutR,int Array[],int nArrLen,int core)
{
ReplaceCore(ulDataL,ulDataR,ulDataOutL,ulDataOutR,Array,nArrLen,core,4,0x80000000);
}
void Replace56To48(ulong ulDataL,ulong ulDataR,ulong *ulDataOutL,ulong *ulDataOutR,int Array[],int nArrLen,int core)
{
ReplaceCore(ulDataL,ulDataR,ulDataOutL,ulDataOutR,Array,nArrLen,core,8,0x80000000);
}
void ReplaceCore(ulong ulDataL,ulong ulDataR,ulong *ulDataOutL,ulong *ulDataOutR,int Array[],int nArrLen,int core,int move,ulong ulComTran)
{
int i;
ulong ulTemp;
ulong ulCompute = ulComTran;
int nLocation;
*ulDataOutL = 0;
*ulDataOutR = 0;
for (i=0; i<nArrLen/2; i++)
{
if (Array[i] > core)
{
nLocation = Array[i]-core-1;
ulCompute >>= nLocation;
ulTemp = ulDataR;
ulTemp &= ulCompute;
if (nLocation>=i)
{
ulTemp <<= (nLocation-i);
}