第四步:如果最后的数据块长度是8字节的话,则在其后加上16进制数字’80 00 00 00 00 00 00 00’,转到第五步。如果最后的数据块长度不足8字节,则在其后加上16进制数字’80’,如果达到8字节长度,则转入第五步;否则在其后加入16进制数字’0’直到长度达到8字节。
第五步:对这些数据块使用MAC过程密钥进行加密。如果安全报文传送支持单长度的MAC DEA密钥,则依照下图的方式使用MAC 过程密钥来产生MAC。
第六步:最终得到是从计算结果左侧取得的4字节长度的MAC。
void DoSSMac(const BYTE* input, intnInLen, const BYTE* key, int nKeyLen, BYTE* output) { BYTE byInitVec[8]; //初始向量 BYTE byTemp[8]; memset(byInitVec, 0x00,sizeof(byInitVec)); memset(byTemp, 0x00,sizeof(byTemp)); memcpy(byInitVec, input, 8); BYTEbySubKey[3][16][48]; //秘钥 memset(bySubKey, 0x01, sizeof(bySubKey)); int i = 0; int j = (nInLen >> 3); //构造并生成SubKeys BYTE nKey = (nKeyLen >> 3) > 3 ?3 : (nKeyLen >> 3); for (i = 0; i < nKey; i++) { SetSubKey(&bySubKey[i], &key[i << 3]); } memcpy(output, input, 8); if (1 == nKey) //单倍长Key(8字节) { j--; for (int i = 0; i <j; ++i) { Xor(input + 8 * (i + 1), output, 8, output); RunDes(output, 0, &bySubKey[0], output); //memcpy(byInitVec, output, 8); //将输出设定为扭转变量 } } <span style="color:#ff0000;"> //转换关系就在这里 else if (2 == nKey) //双倍长Key(16字节) { j -= 2; for (i = 0; i < j;++i) { Xor(input + 8 * (i + 1), output, 8, output); RunDes(output, 0, &bySubKey[0],output); //将输出设定为扭转变量 } Xor(input + 8 * (++i),output, 8, output); //最后一块数据和上面加密结果异或 RunDes(output, 0,&bySubKey[0], output); RunDes(output, 1,&bySubKey[1], output); RunDes(output, 0,&bySubKey[0], output); }</span> else //三倍长Key(24字节) 尚未验证 { //j -= 2; for (i = 0, j =(nInLen >> 3) - 2; i < j; ++i, input += 8) { Xor(input + 8 * (i + 1), output, 8, byTemp); RunDes(byTemp, 0, &bySubKey[0], output); memcpy(byInitVec, output, 8); //将输出设定为扭转变量 } Xor(input + 8 * i,output, 8, output); RunDes(output, 2,&bySubKey[0], output); RunDes(output, 1,&bySubKey[1], output); RunDes(output, 0,&bySubKey[0], output); } }
文/闫鑫原创 转载请注明出处http://blog.csdn.net/yxstars/article/details/38456657