3DES算法,密钥内带负数该如何解决?
向web接口发请求需要进行3DES加密,于是在网上下载了一个类进行处理.(最下方有代码)
Web接口说明上的一个例子
密钥是:
key={-37,-72,-21,91,61,-84,-58,-75,91,71,-22,103,-54,14,-93,88,120,96,54,78,44,102,-114,58};
源字符串是:3033$13311083060$D10$2004-02-24 16:19:27
其数组为:
{51,48,51,51,36,49,51,51,49,49,48,56,51,48,54,48,36,68,49,48,36,50,48,48,52,45,48,50,45,50,52,32,49,54,58,49,57,58,50,55}
加密后的数组是:
{42,-121,-80,127,7,5,-114,-32,112,-105,53,78,-121,-107,14,83,113,84,-1,-52,30,93,7,125,7,84,104,45,-27,82,-35,64,-87,-11,-91,95,66,-24,-81,125,36,-21,38,-121,-25,-1,-73,125}
使用网上下载的类通过加密解密再加密的3DES过程,得到第一个字符是(58,.....)和说明给的不符,分析代码发现类内的key定义是无符号的char型,而说明给的key是带负号的.强行的将代码内unsinged去掉必然带来结果的错误,而网上也没有找到相关的解决.
又试着在网上找了个正数的key案例实验,
下述数据为16进制数
key:57415443484441544154696d65434f53
数据:47972DC678443425
加密后结果:19ECE1DC4C0BD6A6
结果也是不一样,这就让我怀疑代码内哪里出错了,但是我对这3DES算法是一头雾水.
........void C3DES::make(BOOL FirstFlag)//操作过程:根据事先预置在key[8],m[8],ed_flag中的数据进行//加密\脱密操作,将结果保存在c[8]中。参数FirstFlag标识m[8]中//是否是首块数据。{ unsigned int j; if(FirstFlag==TRUE) pro_key(); for(j=0;j<64;j++) pc[j]=pc0[j]; first_p(); fction(); unsigned char *pointer=(unsigned char *)x; for(j=0;j<4;j++) m[3-j]=*pointer++; for(j=0;j<4;j++) m[7-j]=*pointer++; for(j=0;j<64;j++) pc[j]=pc0_v[j]; first_p(); pointer=(unsigned char *)x; for(j=0;j<4;j++) c[3-j]=*pointer++; for(j=0;j<4;j++) c[7-j]=*pointer++; }void C3DES::pro_key(void)//操作过程:以pc1[56],pc2[48],bytebit[8],bigbyte[24],//rotate[16]及key[8]中的数据为入参,进行运算后得到结果保存//到k[16][8]中,并根据ed_flag的值是否是decrypt来决定是否对//k[16][8]中的结果进行调整。{ unsigned short i,j,l; unsigned char pc1m[56],pcr[56],k_m[16][8]; unsigned long k1[16],k2[16]; for(j=0;j<56;j++) { l=pc1[j]; pc1m[j]=(key[l>>3]&bytebit[l&07]) ? 1:0 ; //所有能使(l & 0x07)的值为7即用来访问bytebit[7] //的l值有:7,15,23,31,39,47,55,63,而这些值在pc1[56] //的定义中都没有。也就是说bytebit[7](=0x01)永远 //无法被访问。因此密钥key[8]的各字节数据的最低位 //总是被忽略。 } for(i=0;i<16;i++) { k1[i]=k2[i]=0; for(j=0;j<28;j++) { l=j+rotate[i]; if(l<28) pcr[j]=pc1m[l]; else pcr[j]=pc1m[l-28]; } for(j=28;j<56;j++) { l=j+rotate[i]; if(l<56) pcr[j]=pc1m[l]; else pcr[j]=pc1m[l-28]; } for(j=0;j<24;j++) { if(pcr[pc2[j]]) k1[i]|=bigbyte[j]; if(pcr[pc2[j+24]]) k2[i]|=bigbyte[j]; } k[i][0]=(unsigned char)((k1[i]>>18)&0x3f); k[i][1]=(unsigned char)((k1[i]>>12)&0x3f); k[i][2]=(unsigned char)((k1[i]>>6)&0x3f); k[i][3]=(unsigned char)(k1[i]&0x3f); k[i][4]=(unsigned char)((k2[i]>>18)&0x3f); k[i][5]=(unsigned char)((k2[i]>>12)&0x3f); k[i][6]=(unsigned char)((k2[i]>>6)&0x3f); k[i][7]=(unsigned char)(k2[i]&0x3f); } if(ed_flag==decrypt) { for(i=0;i<16;i++) for(j=0;j<8;j++) k_m[i][j]=k[15-i][j]; for(i=0;i<16;i++) for(j=0;j<8;j++) k[i][j]=k_m[i][j]; }}void C3DES::first_p(void)//操作过程:以bytebit[8],bigbyte1[32],pc[64]及m[8]中的数据//为入参,进行运算后得到结果保存到x[2]中。{ unsigned char pcm[64]; unsigned short j,l; x[0]=x[1]=0; for(j=0;j<64;j++) { l=pc[j]; pcm[j]=(m[l>>3]&bytebit[l&07]) ? 1:0; } for(j=0;j<32;j++) { if(pcm[j]) x[0]|=bigbyte1[j]; if(pcm[j+32]) x[1]|=bigbyte1[j]; }}void C3DES::expand_x(void)//操作过程:以数组x[2]中的数据元素x[1]的值为入参,进行运算//后得到结果保存到s_in[8]中。{ s_in[0]=(unsigned char)((x[1]>>27)^((x[1]&0x1)<<5)); s_in[1]=(unsigned char)((x[1]&0x1f800000)>>23); s_in[2]=(unsigned char)((x[1]&0x1f80000)>>19); s_in[3]=(unsigned char)((x[1]&0x1f8000)>>15); s_in[4]=(unsigned char)((x[1]&0x1f800)>>11); s_in[5]=(unsigned char)((x[1]&0x1f80)>>7); s_in[6]=(unsigned char)((x[1]&0x1f8)>>3); s_in[7]=(unsigned char)(((x[1]&0x1f)<<1)^(x[1]>>31));}void C3DES::fction(void)//操作过程:以sp0[64],sp1[64],sp2[64],sp3[64],sp4[64],//sp5[64],sp6[64],sp7[64]及x[2],k[16][8],s_in[8]中的数//据为入参,进行运算后得到结果保存到x[2]中。 { unsigned short i,j; unsigned long xm; for(i=0;i<16;i++) { xm=x[1]; expand_x(); for(j=0;j<8;j++) s_in[j]^=k[i][j]; x[1] =sp0[s_in[0]]; x[1]^=sp1[s_in[1]]; x[1]^=sp2[s_in[2]]; x[1]^=sp3[s_in[3]]; x[1]^=sp4[s_in[4]]; x[1]^=sp5[s_in[5]]; x[1]^=sp6[s_in[6]]; x[1]^=sp7[s_in[7]]; x[1]=x[0]^x[1]; x[0]=xm; } xm=x[1]; x[1]=x[0]; x[0]=xm;}BOOL C3DES::DoDES3( unsigned char EDFlag, //EDFlag是加\脱密标志,0表示加密,1表示脱密 unsigned char databuf[8], //DataBuf将被处理的明文或密文的缓冲区,并兼作输出缓冲区 unsigned char keybuf[8] //8byte的密钥缓冲区 ){ ed_flag=EDFlag; //初始化密钥 memcpy(key, keybuf, 8); //将64 bit待处理数据置入m[8] memcpy(m, databuf, 8); //主加密\脱密算法 make(TRUE); memcpy(databuf, c, 8); return TRUE;}BOOL C3DES::DoDES3(int nWay,unsigned char* pSrc,int nSrcSize,unsigned char* pDes, unsigned char pKey[8]){ int nSize = nSrcSize / 8 * 8; if (nSize < nSrcSize) nSize += 8; unsigned char* pBuff = new unsigned char[nSize]; ZeroMemory(pBuff,nSize); memcpy(pBuff,pSrc,nSrcSize); int i; unsigned char *p = pBuff; for (i = 0 ; i < nSize / 8; ++i) { if (FALSE == DoDES3(nWay,p,pKey)) return FALSE; p += 8; } memcpy(pDes,pBuff,nSize); delete[] pBuff; return TRUE;}
C3DES desWorker;.......................... unsigned char testA[] = {0x47,0x97,0x2D,0xC6,0x78,0x44,0x34,0x25}; unsigned char key[] = {0x57,0x41,0x54,0x43,0x48,0x44,0x41,0x54,0x41,0x54,0x69,0x6d,0x65,0x43,0x4f,0x53}; unsigned char key1[] = {0x57,0x41,0x54,0x43,0x48,0x44,0x41,0x54}; unsigned char key2[] = {0x41,0x54,0x69,0x6d,0x65,0x43,0x4f,0x53}; unsigned char key3[] = {0x57,0x41,0x54,0x43,0x48,0x44,0x41,0x5}; int nSize = sizeof(testA)/sizeof(testA[0]) / 8 * 8; if (nSize < sizeof(testA)/sizeof(testA[0])) nSize += 8; unsigned char *testDes1 = new unsigned char[nSize]; unsigned char *testDes2 = new unsigned char[nSize]; unsigned char *testDes3 = new unsigned char[nSize]; CString strTest1; desWorker.DoDES3(0, testA, sizeof(testA)/sizeof(testA[0]), testDes1, key1); strTest1.Format("%s", testDes1); desWorker.DoDES3(1, testDes1, nSize, testDes2, key2); strTest1.Format("%s", testDes2); desWorker.DoDES3(0, testDes2, nSize, testDes3, key3); strTest1.Format("%s, %d", testDes3, testDes3[0]);............