DES(ecb)加密

来源:互联网 发布:计算机网络就业 知乎 编辑:程序博客网 时间:2024/05/19 15:20

因为工作关系,涉及到了DES和3DES,查阅了部分博客,发现写的都有些差异,加密结果与现有的工具机密结果不对,所以整理了下。先介绍下对称密码算法DES

DES算法具有极高安全性,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。而56位长的密钥的穷举空间为256,这意味着如果一台计算机的速度是每一秒种检测一百万个密钥,则它搜索完全部密钥就需要将近2285年的时间,可见,这是难以实现的,当然,随着科学技术的发展,当出现超高速计算机后,我们可考虑把DES密钥的长度再增长一些,以此来达到更高的保密程度



先贴上代码


#include<memory.h>#include "DES.h"#include<stdio.h>char szKeys[16][48];//存储16组48bit密钥char szCipherText[64];//存储64位密文char szplaintText[64];//存储64位明文char szCiphertextInBytes[8];//储存8位密文char szPlaintextInBytes[8];//储存8位明文字符串char szCiphertextInBinary[65]; //储存二进制密文(64个Bits) char szCiphertextInHex[17]; //储存十六进制密文,最后一位存'\0'// permuted choice table (PC1)const static char PC1_Table[56] = {//64位密钥去掉8,16,24...等8位奇偶位,对PC1_Table进行置换,密钥A=0--27,57, 49, 41, 33, 25, 17,  9,  1, 58, 50, 42, 34, 26, 18,  //B=28--56 [注:数字为数组下标]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};// permuted choice key (PC2)const static char PC2_Table[48] = {//A,B俩个28bit的密钥进行i次迭代后,组合成56bit密钥,对PC2_Table进行置换,14, 17, 11, 24,  1,  5,  3, 28, 15,  6, 21, 10,//生成子密钥,子密钥与进行i次迭代的数据进行位异或操作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};// number left rotations of pc1 const static char Shift_Table[16] = { //第i次迭代次数1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};// initial permutation (IP)const static char IP_Table[64] = {//明文数据对此表进行置换,得到新的64bit数据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};// expansion operation matrix (E)const static char E_Table[48] = {//把IP_Table置换过的明文数据分为left,right两部分,left不变,right对E_Table进行扩展,成48bit32,  1,  2,  3,  4,  5,  4,  5,  6,  7,  8,  9,//然后与i次迭代生成的子密钥进行位异或操作,得到新的right数据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};// The (in)famous S-boxes const static char S_Box[8][4][16] = {//把新的到的right48bit数据压缩成32bit,1.把48bit数据分割成8个6bit数据,// S12.把6bit的数据第1位和第6位组合位此表纵坐标,2-5位横坐标,得到相关值14,  4,13,  1,  2, 15, 11,  8,  3, 10,  6, 12,  5,  9,  0,  7,//3.把数据转为4bit  S[i]对应i次迭代的数据0, 15,  7,  4, 14,  2, 13,  1, 10,  6, 12, 11,  9,  5,  3,  8,//4.最终得到32bit数据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,// S2 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,// S3 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,// S4 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,// S5 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,// S6 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,// S7 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,// S8 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};// 32-bit permutation function P used on the output of the S-boxes const static char P_Table[32] = {//将得到的32bit right数据按P_Table进行置换,得到新数据right16, 7, 20, 21, 29, 12, 28, 17, 1,  15, 23, 26, 5,  18, 31, 10,//将right与left进行位异或操作,结果赋值给right2,  8, 24, 14, 32, 27, 3,  9,  19, 13, 30, 6,  22, 11, 4,  25 //将本次的原始right值赋值给left};//得到的left和right进行下一次迭代操作// final permutation IP^-1 const static char IPR_Table[64] = {//将left和right结合,按IPR_Table表进行置换,结果为最终的加密数据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};extern "C" void initialization(){memset(szKeys, 0, 16 * 48);memset(szCipherText, 0, 64);memset(szplaintText, 0, 64);memset(szCiphertextInBytes, 0, 8);memset(szPlaintextInBytes, 0, 8);memset(szCiphertextInBinary, 0, 65);memset(szCiphertextInHex, 0, 17);}extern "C" char *DES_GetszCiphertextInBytes(){return szCiphertextInBytes;}extern "C" char *DES_GetszPlaintextInBytes(){return szPlaintextInBytes;}extern "C" void DES_InitializeKey(char* srcBytes){char sz_64key[64] = { 0 };char sz_56key[56] = { 0 };DES_Bytes2Bits(srcBytes, sz_64key, 64);for (int i = 0; i < 56; i++)    //置换64位密钥为56位{sz_56key[i] = sz_64key[PC1_Table[i]-1];}DES_CreateSubKey(sz_56key);}extern "C" void DES_CreateSubKey(char* sz_56key){int i, j;char sz_leftKey[28] = { 0 };char sz_rightKey[28] = { 0 };char sz_tempL[28] = { 0 };char sz_tempR[28] = { 0 };char sz_temp56[56] = { 0 };memcpy(sz_leftKey, sz_56key, 28);memcpy(sz_rightKey, sz_56key+28, 28);for (i = 0; i < 16; i++){memcpy(sz_tempL, sz_leftKey + Shift_Table[i], 28 - Shift_Table[i]); //移位操作memcpy(sz_tempL + 28 - Shift_Table[i], sz_leftKey, Shift_Table[i]);memcpy(sz_tempR, sz_rightKey + Shift_Table[i], 28 - Shift_Table[i]);//移位操作memcpy(sz_tempR + 28 - Shift_Table[i], sz_rightKey, Shift_Table[i]);memcpy(sz_temp56, sz_tempL, 28);memcpy(sz_temp56+28, sz_tempR, 28);for (j = 0; j < 48; j++){szKeys[i][j] = sz_temp56[PC2_Table[j]-1];  //生成16组48位的子密钥}memcpy(sz_leftKey, sz_tempL, 28);memcpy(sz_rightKey, sz_tempR, 28);}}extern "C" void DES_EncryptData(char* _srcBytes) //加密8位字符串{int i = 0,j=0;char sz_srcBits[64] = { 0 };char sz_shiftIP[64] = { 0 };char sz_srcL[32] = { 0 };char sz_srcR[32] = { 0 };char sz_resultBits[64] = { 0 };DES_Bytes2Bits(_srcBytes, sz_srcBits, 64);  for (i = 0; i < 64; i++){sz_shiftIP[i] = sz_srcBits[IP_Table[i]-1];  //64位明文置换}memcpy(sz_srcL, sz_shiftIP, 32);memcpy(sz_srcR, sz_shiftIP + 32, 32);for (i = 0; i<16; i++)    //16次迭代操作{DES_FunctionF(sz_srcL, sz_srcR, i);}memcpy(sz_resultBits, sz_srcR, 32);  //组合left、rightmemcpy(sz_resultBits + 32, sz_srcL, 32);for (j = 0; j<64; j++){szCipherText[j] = sz_resultBits[IPR_Table[j] - 1];   //进行逆置换}DES_Bits2Bytes(szCiphertextInBytes, szCipherText, 64);}extern "C" void DES_FunctionF(char* sz_srcL, char* sz_srcR, unsigned int iKey){int i = 0;char sz_P32[32] = { 0 };char sz_R[32] = { 0 };char sz_48R[48] = { 0 };char sz_key[48] = { 0 };char sz_xor[48] = { 0 };char compressData32[32] = { 0 };for (i = 0; i < 48; i++)//right 扩展{sz_48R[i] = sz_srcR[E_Table[i]-1];}memcpy(sz_key, szKeys[iKey], 48);DES_XOR(sz_48R, sz_key, 48, sz_xor); //扩展后的right与子密钥进行异或操作DES_CompressFunc(sz_xor, compressData32);//异或结果进行压缩成32bitfor (i = 0; i<32; i++){sz_P32[i] = compressData32[P_Table[i] - 1]; // 压缩后的数据进行置换}DES_XOR(sz_P32, sz_srcL, 32, sz_R);  //置换后的right与left数据进行异或memcpy(sz_srcL, sz_srcR, 32);    //传入的初始right赋值给left作为下次的leftmemcpy(sz_srcR, sz_R, 32);//左右异或生成的right的值作为下次运算的right}extern "C" void DES_XOR(char* szParam1, char* szParam2, unsigned int uiParamLength, char* szReturnValueBuffer)//异或操作{unsigned int i = 0;for (i = 0; i<uiParamLength; i++){szReturnValueBuffer[i] = szParam1[i] ^ szParam2[i];}}extern "C" void DES_CompressFunc(char* _src48, char* _dst32)//压缩数据{char tempBit[8][6] = { 0 };char dest4bit[4] = { 0 };int i = 0, X = 0, Y = 0, j = 0;for (i = 0; i<8; i++){memcpy(tempBit[i], _src48 + i * 6, 6);X = (tempBit[i][0] << 1 )+ (tempBit[i][5]);Y = 0;for (j = 1; j<5; j++){Y += tempBit[i][j] << (4 - j);}DES_Int2Bits(S_Box[i][X][Y], dest4bit);memcpy(_dst32 + i * 4, dest4bit, 4);}}extern "C" void DES_Bytes2Bits(char *srcBytes, char* dstBits, unsigned int sizeBits){unsigned int i = 0;for (i = 0; i < sizeBits; i++)dstBits[i] = ((srcBytes[i >> 3] << (i & 7)) & 128) >> 7;}extern "C" void DES_Bits2Bytes(char *dstBytes, char* srcBits, unsigned int sizeBits){unsigned int i = 0;memset(dstBytes, 0, sizeBits >> 3);for (i = 0; i < sizeBits; i++)dstBytes[i >> 3] |= (srcBits[i] << (7 - (i & 7)));}extern "C" void DES_Int2Bits(unsigned int _src, char* dstBits){unsigned int i = 0;for (i = 0; i < 4; i++)dstBits[i] = ((_src << i) & 8) >> 3;}extern "C" void DES_Bits2Hex(char *dstHex, char* srcBits, unsigned int sizeBits){unsigned int i = 0, j = 0;memset(dstHex, 0, sizeBits >> 2);for (i = 0; i < sizeBits; i++) //convert to int 0-15dstHex[i >> 2] += (srcBits[i] << (3 - (i & 3)));for (j = 0; j < (sizeBits >> 2); j++)  dstHex[j] += dstHex[j] > 9 ? 55 : 48; //convert to char '0'-'F'}                          extern "C" void DES_Hex2Bits(char *srcHex, char* dstBits, unsigned int sizeBits){unsigned int i = 0, j = 0;memset(dstBits, 0, sizeBits);for (i = 0; i < (sizeBits >> 2); i++)srcHex[i] -= srcHex[i] > 64 ? 55 : 48; //convert to char int 0-15for (j = 0; j < sizeBits; j++)dstBits[j] = ((srcHex[j >> 2] << (j & 3)) & 15) >> 3;}extern "C" void DES_DecryptData(char* _srcBytes) //解密8位字符串{int i = 0, j = 0;char sz_srcBits[64] = { 0 };char sz_shiftIP[64] = { 0 };char sz_srcL[32] = { 0 };char sz_srcR[32] = { 0 };char sz_resultBits[64] = { 0 };DES_Bytes2Bits(_srcBytes, sz_srcBits, 64);for (i = 0; i < 64; i++){sz_shiftIP[i] = sz_srcBits[IP_Table[i] - 1];  }memcpy(sz_srcR, sz_shiftIP, 32);memcpy(sz_srcL, sz_shiftIP + 32, 32);for (i = 0; i<16; i++)    {DES_FunctionF(sz_srcR, sz_srcL, 15 - i);}memcpy(sz_resultBits, sz_srcL, 32);  memcpy(sz_resultBits + 32, sz_srcR, 32);for (j = 0; j<64; j++){szplaintText[j] = sz_resultBits[IPR_Table[j] - 1];   }DES_Bits2Bytes(szPlaintextInBytes, szplaintText, 64);}

一些概念就不多说了,网上一大堆
具体操作,上面注释已经说的差不多了,也就不多说了,只有几个注意的,置换表是按1开始算的,所以,我们置换的时候需要-1。还有就是一般我们使用的时候,都是16进制
的字符串进行加密,可以使用自己将8字节的字符串转为hex,就可以实现了。还有就是加密的结果用明文形式直接输出的话,会乱码,所以我们需要将它转为十六进制,或者
用base64进行转码(网上的一些在线工具,一般都是用了base64的,查看源码可以看到)。
然后就是关于解码问题,把right和left对换一下,因为right是上次的left和right异或的结果,而上次的right赋值给了left,所以调换下位置就行。keys从15开始。
代码借鉴了一位大佬的http://www.cnblogs.com/erwin/archive/2009/04/14/1435288.html,取来阅读理解了下。
有啥问题,欢迎指正。

1 0
原创粉丝点击