DES算法的一次执行中将进行16轮迭代加密;
从原始的56位密钥中得到16个轮密钥k,每个轮密钥ki是48位;
轮密钥也叫子密钥;
下面看一下子密钥的生成过程;
大体过程是这样;看下图,
此图来自 34.《密码学》.DES算法原理讲解_子密钥生成及总结_哔哩哔哩_bilibili
64位的密钥,去掉8位校验位,剩下56位;
按PC-1表进行置换,打乱顺序;然后分成2个28位;一个28位是C0,一个28位是D0,
然后要进行循环左移,循环左移要移1位或2位,根据是第几轮来判断,可查上图的循环左移查表;
移位之后得到Ci和Di,i是轮数;
把Ci和Di组合得到56位;
得到的56位按PC-2表进行置换,置换中有8位会被去除,得到此轮的48位子密钥ki;
PC-1表是56位,PC-2表是48位;
或者更简洁看下图;
此图来自,DES加密解密算法(简单、易懂、超级详细)_des加密算法_sunny-ll的博客-CSDN博客
过程为:64位密钥输入,PC1置换,分成2个28位,循环左移,得到一个56位,PC2置换,得到48位子密钥ki;
看了一下DES加密算法代码;还没完全看清楚;
算法描述中的位应该是二进制bit位;
代码中操作并不是用C语言的位运算;应该是一个二进制串例如 11001010 ,是作为一个字符串,取字符串的每一个来按算法操作;完了之后再把二进制的字符串转换为整型,由整型可取得字符的ASCII码;应该是这样;
它的PC1置换代码是这样的,
int pc1Table[56] =
{
57,49,41,33,25,17,9,1,
58,50,42,34,26,18,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
};
string miyao, miyaoBinary, pc1MiyaoBinary;
//从64bit密钥中依据PC-1盒子取出56bit
for (i = 0; i < 56; i++)
{
pc1MiyaoBinary += miyaoBinary[pc1Table[i] - 1];
}
其中 miyaoBinary 和 pc1MiyaoBinary 是string类型;
它的代码中还有2个函数是实现二进制的字符串和整型数之间的转换,
int binaryToInt(string s),输入一个二进制的字符串返回整型数;
string intToBinary(int i),输入一个整数返回二进制的字符串;
下面单独先把这2个函数在MFC中看一下;我把它的string类型换成了MFC的CString;
int binaryToInt(CString );
CString intToBinary(int );
void CInbyView::OnDraw(CDC* pDC)
{
CInbyDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
CString str1;
CString b1 = "0101";
int b2 = binaryToInt(b1);
str1.Format("0101的整数:%d", b2);
pDC->TextOut(50, 50, str1);
CString b3 = "1100101";
int b4 = binaryToInt(b3);
str1.Format("1100101的整数:%d", b4);
pDC->TextOut(50, 80, str1);
str1 = intToBinary(12);
pDC->TextOut(50, 110, "12的二进制:" + str1);
CString str3 = intToBinary(14);
pDC->TextOut(50, 140, "14的二进制:" + str3);
CString str4 = intToBinary(37);
pDC->TextOut(50, 170, "37的二进制:" + str4);
}
//二进制转整型
int binaryToInt(CString s)
{
int i, result = 0, p = 1;
for (i = s.GetLength() - 1; i >= 0; i--)
{
result += ((s[i] - '0') * p); //数字字符转成字符
p *= 2;
}
return result;
}
//整型转二进制
CString intToBinary(int i)
{
int k = 0;
CString result;
while (k < 4) //此处,处理进入S盒后取出的数据转为2进制,此处最多用4bit
{
if (i)
{
result += ((i % 2) + '0');
i /= 2;
}
else result += '0';
k++;
}
result.MakeReverse();
return result;
}
输出如下;
其中 intToBinary() 根据它的说明最多用4bit;37的二进制如下,输入37时只返回低4位;
有时间继续;