(1)64bit的明文经过一个P盒的初始置换,然后分成左右两个部分
(2)进行十六轮的加密操作,其中上一轮的右部分复制下一轮的左部分,上一轮的右部分经F轮函数操作的结果与该轮左部分进行异或,得出的结果复制给下一轮的右部分。注意,在第16轮时,R16=R15,L16=L15⊕F(R15,K16)
(3)把最后的一轮得出得左右部分结合在一起,在进行一个P盒得置换,得到密文
F轮函数
(1)进入的32bit的右部分,经过扩展P盒的扩展变成48bit
(2)扩展P盒得出的48bit结果与48bit的密钥进行异或
(3)上一步异或的48bit结果在进行8个S盒压缩成32bit
(4)经S盒压缩后的32bit信息再经过一个P盒的置换,得出F轮函数的操作结果
密钥的产生
(1)64bit的密钥信息,经过P盒压缩,变成56bit,并分成左右28bit两个部分
(2)左右了两个部分分别根据每轮移动的值进行循环左移
(3)把循环左移后的两部分密钥重新按左右顺序结合成58bit
(4)58bit的信息在进行一个P盒的压缩变成48bit的该轮密钥K
2.算法框图 3.详详细解释原理参考DES加密算法_樱木之的博客-CSDN博客_csdn des算法
4.C++代码实现 (1)说明本算法实现了对一个64bit的十六进制信息的加密,主要是把二进制信息储存在字符串中,通过操作字符串下标来进行替换,异或等操作
(2)所用函数string BinaryToHex(string binary)//二进制转十六进制,输入二进制的字符串,输出十六进制的字符串
string BinaryToHex(string binary)//二进制转十六进制,输入十六进制的字符串,输出二进制的字符串
string DeciTo4Bin(int n)//十进制转4位二进制,在F轮函数中S盒压缩时用到
string InitialReplace(string binmessage)//初始置换函数,64bit明文的初始置换
string EndInReplace(string binary64)//输出密文前的置换,逆初始置换
string ExtendTrans(string binary32)//扩展变换,F轮函数中的扩展变换
string XOR(string str1, string str2)//两个字符串的异或
string FSboxPress(string binary48)//输出F轮函数中,S盒的压缩,以及压缩后的P盒置换的结果
string KPremuSel1(string keybinary64)//密钥的置换选择1,把64bit的密钥变成54bit
string KeyRoundCreate(string & C0, string& D0, int n)//轮密钥的生成,输入:左28密钥二进制,右28密钥二进制,左移位数。
//输出:48位的二进制密钥,注意C0,D0是引用的传递
void Encryption()//加密函数
(3)代码
#pragma once #include#include using namespace std; //初始时的IP置换盒64bit->32bit+32bit static const int P[64]= { 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 }; //最后输出时的逆初始置换IP:32bit+32bit->64bit static const int IPI[64] = { 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 }; //F轮函数中的EP扩展变换盒,32bit-48bit static const int FEP[48]= { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 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 }; //F轮函数中的8个S压缩盒;48bit->32bit static const int FS8[32][16]= { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7, //S1 0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8, 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, 15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10, //S2 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, 10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8, //S3 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, 7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15, //S4 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, 2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,//S5 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, 12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,//S6 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, 4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,//S7 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, 13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,//S8 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 }; //F轮函数中的置换运算P盒32bit->32bit static const int FP[32]= { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 }; //密钥生产过程中的置换选择压缩P1盒64bit->28bit+28bit static const int CP1[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 }; //密钥生产过程中的置换选择压缩P2盒28bit+28bit->48bit static const int CP2[48]= { 14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 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 }; //密钥生产过程中每轮的循环左移的数 static const int CEnRotateLeft[16]= { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 }; //各种辅助函数 string HexToBinary(string hex)//十六进制变二进制 { string binnum = ""; int n = hex.size(); for (int j = 0; j < hex.length(); j++) { switch (hex[j]) { case '0':binnum += "0000"; break; case '1':binnum += "0001"; break; case '2':binnum += "0010"; break; case '3':binnum += "0011"; break; case '4':binnum += "0100"; break; case '5':binnum += "0101"; break; case '6':binnum += "0110"; break; case '7':binnum += "0111"; break; case '8':binnum += "1000"; break; case '9':binnum += "1001"; break; case 'A':binnum += "1010"; break; case 'B':binnum += "1011"; break; case 'C':binnum += "1100"; break; case 'D':binnum += "1101"; break; case 'E':binnum += "1110"; break; case 'F':binnum += "1111"; break; default: break; } } return binnum; } string BinaryToHex(string binary)//二进制转十六进制 { string hex = ""; int temp; for (int i = 0; i < binary.size(); i+=4) { //转化为int型 temp = ((int)binary[i]-(int)'0') * 8 + ((int)binary[i+1] - (int)'0') * 4 + ((int)binary[i+2] - (int)'0') * 2 + ((int)binary[i+3] - (int)'0') * 1; //cout << temp; if (temp >= 10) { switch (temp) { case 10:hex += "A"; break; case 11:hex += "B"; break; case 12:hex += "C"; break; case 13:hex += "D"; break; case 14:hex += "E"; break; case 15:hex += "F"; break; } } else { hex += to_string(temp); } } return hex; } string DeciTo4Bin(int n)//十进制转4位二进制 { string decimal = ""; while (n) { decimal += to_string(n % 2); n = n / 2; } //反转一下 for (int i = 0; i < decimal.size() / 2; i++) { char temp; temp = decimal[i]; decimal[i] = decimal[decimal.size() - 1 - i]; decimal[decimal.size() - 1 - i] = temp; } switch (4-decimal.size()) { case 1:decimal = "0"+ decimal; break; case 2:decimal = "00" + decimal; break; case 3:decimal = "000" + decimal; break; case 4:decimal = "0000" + decimal; break; default: break; } return decimal; } //开始 string InitialReplace(string binmessage)//初始置换函数 { string binary = ""; for (int i = 0; i < 64; i++) { binary += binmessage[P[i] - 1]; } return binary; } //最后 string EndInReplace(string binary64) { string out64 = ""; for (int i = 0; i < 64; i++) { out64 += binary64[IPI[i] - 1]; } return out64; } //F论函数 string ExtendTrans(string binary32)//扩展变换 { string out48 = ""; for (int i = 0; i < 48; i++) { out48 += binary32[FEP[i] - 1]; } return out48; } string XOR(string str1, string str2)//两个字符串的异或 { string outcome = ""; for (int i = 0; i < str1.size(); i++) { if (str1[i] == str2[i]) outcome += "0"; else { outcome += "1"; } } return outcome; } string FSboxPress(string binary48) { int n = 1;//从第一个S盒开始 string binary32 = ""; for (int i = 0; i < binary48.size(); i+=6) { int y = ((int)binary48[i] - (int)'0') * 2 + ((int)binary48[i + 5] - (int)'0') * 1;//获取S盒第几行 int x = ((int)binary48[i + 1] - (int)'0') * 8 + ((int)binary48[i + 2] - (int)'0') * 4//获取S盒的第几列 + ((int)binary48[i + 3] - (int)'0') * 2 + ((int)binary48[i + 4] - (int)'0') * 1; int tem = FS8[y + (n - 1) * 4][x];//获取该S盒行列位置下的十进制 binary32 += DeciTo4Bin(tem);//把十进制转化位二进制,并复制给要输出的字符串 n++;//调用下一个S盒 } string premutation = ""; for (int i = 0; i < 32; i++) { premutation += binary32[FP[i] - 1]; } return premutation; } //K密钥 string KPremuSel1(string keybinary64)//密钥的置换选择1 { string out56 = ""; for (int i = 0; i < 56; i++) { out56 += keybinary64[CP1[i] - 1]; } return out56; } string KeyRoundCreate(string & C0, string& D0, int n)//轮密钥的生成,输入:左28密钥二进制,右28密钥二进制,左移位数。 //输出:48位的二进制密钥,注意C0,D0是引用的传递 { string Cnext = "", Dnext = "";//临时储存左移的结果 string out48;//把左移的结果拼接 for (int i = n; i < C0.size(); i++)//对C0循环左移 { Cnext += C0[i]; Dnext += D0[i]; } for (int i = 0; i < n; i++)//对D0循环左移 { Cnext += C0[i]; Dnext += D0[i]; } //cout << "C0循环左移:" << Cnext << endl; //cout << "D0循环左移:" << Dnext << endl; //把传进来的左右两个密钥改为下一轮的新左右两密钥,提供给下一轮使用 C0 = Cnext; D0 = Dnext; string temp = Cnext + Dnext; //拼接的结果,进行置换选择2(压缩P盒) for (int i = 0; i < 48; i++) { out48 += temp[CP2[i] - 1]; } return out48; } //加密 void Encryption() { string key = HexToBinary("AABB09182736CCDD");//密钥二进制 string message = HexToBinary("123456ABCD132536");//明文二进制 //密钥 string keypresel1 = KPremuSel1(key);//密钥压缩 string keyleft28 = keypresel1.substr(0, 28); string keyright28 = keypresel1.substr(28, 28); string premessage = InitialReplace(message);//初始置换IP,64bit-64bit //把初始的message分为左右两个部分 string messleft = premessage.substr(0, 32); string messright = premessage.substr(32, 32); cout << "轮序0 " << "左:" << BinaryToHex(messleft) << " 右:" << BinaryToHex(messright) << endl; //获取第一轮密钥 for (int i = 0; i < 16; i++) { string kdynextbinary = KeyRoundCreate(keyleft28, keyright28, CEnRotateLeft[i]);//获取轮密钥 string Fextendres = ExtendTrans(messright);//F论函数对右边明文进行扩展,32bit-48bit string firstxor = XOR(Fextendres, kdynextbinary);//扩展的结果与轮密钥异或 string sboxpress = FSboxPress(firstxor);//异或的结果进行8个S盒的压缩,以及一个P盒的置换 string newright = XOR(messleft, sboxpress);//上步得到的结果在与左边的明文进行异或 if (i < 15) { cout << "轮序" << i + 1 << " 左:" << BinaryToHex(messright) << " 右:" << BinaryToHex(newright) << " 密钥" << BinaryToHex(kdynextbinary) << endl << endl; } else { cout << "轮序" << i + 1 << " 左:" << BinaryToHex(newright) << " 右:" << BinaryToHex(messright) << " 密钥" << BinaryToHex(kdynextbinary) << endl << endl; } //下一轮的新参数; if (i < 15) { messleft = messright;//下一轮的左message messright = newright;//下一轮的右message } else { messleft = newright; } } string F16res = messleft + messright; cout << "左右部分拼接在一起:" << BinaryToHex(F16res) << endl; string endoutcom = InitialReplace(F16res); cout << "密文:" << BinaryToHex(endoutcom) << endl; }



