IT

数据加密标准 (DES)

添加时间:2022-02-27 15:42:18

数据加密标准 (DES)被发现容易受到非常强大的攻击,因此,发现 DES 的流行度略有下降。

DES 是一种分组密码,以每个 64 位大小的块的形式加密数据,这意味着 64 位纯文本作为 DES 的输入,DES 产生 64 位密文。加密和解密使用相同的算法和密钥,略有不同。密钥长度为 56 位。基本思想如图所示。


我们已经提到 DES 使用 56 位密钥。实际上,初始密钥由 64 位组成。但是,在 DES 过程开始之前,密钥的每 8 位都会被丢弃,以生成 56 位的密钥。也就是说,比特位置 8、16、24、32、40、48、56 和 64 被丢弃。 


因此,丢弃密钥的每 8 位会从原始 64 位密钥生成一个 56 位密钥。

DES 基于密码学的两个基本属性:替换(也称为混淆)和转置(也称为扩散)。DES 由 16 个步骤组成,每个步骤称为一轮。每轮执行替换和转置步骤。现在让我们讨论 DES 中的广义步骤。 


第一步,将 64 位纯文本块移交给初始置换 (IP) 函数。

初始排列是在纯文本上执行的。

接下来,初始置换(IP)产生置换块的两半;表示左纯文本 (LPT) 和右纯文本 (RPT)。

现在每个 LPT 和 RPT 都要经过 16 轮加密过程。

最后,LPT 和 RPT 重新加入,并在组合块上执行最终置换 (FP)

此过程的结果产生 64 位密文。



初始排列 (IP) – 

正如我们所指出的,初始排列 (IP) 只发生一次,并且发生在第一轮之前。它建议 IP 中的转置应该如何进行,如图所示。 

例如,IP 将原始明文块的第 1 位替换为原始明文的第 58 位,将第 2 位替换为原始明文块的第 50 位,以此类推。

这不过是原始纯文本块的位位置的杂耍。相同的规则适用于图中所示的所有其他位位置。


正如我们在 IP 完成后注意到的那样,生成的 64 位置换文本块被分成两个半块。每个半块由 32 位组成,而 16 轮中的每一轮又由图中概述的广泛级别步骤组成。 


第 1 步:密钥转换—— 

我们注意到,通过丢弃初始密钥的每 8 位,将初始 64 位密钥转换为 56 位密钥。因此,对于每个 56 位密钥可用。从这个 56 位密钥中,使用称为密钥转换的过程在每一轮中生成一个不同的 48 位子密钥。为此,56 位密钥分为两半,每半 28 位。根据轮次,这些半部循环左移一个或两个位置。

例如,如果轮数为 1、2、9 或 16,则其他轮的移位仅由位置完成,则循环移位由两个位置完成。每轮移动的关键比特数如图所示。


在适当的移位之后,选择 56 位中的 48 位。对于选择 56 位中的 48 位,该表如下图所示。例如,移位后,第 14 位移动到第一个位置,第 17 位移动到第二个位置,依此类推。如果我们仔细观察这张表,我们会发现它只包含 48 位的位置。与其他 7 位一样,第 18 位被丢弃(我们不会在表中找到),以将 56 位密钥减少为 48 位密钥。由于密钥转换过程涉及置换以及选择原始 56 位密钥的 48 位子集,因此称为压缩置换。


由于这种压缩置换技术,每一轮都使用不同的密钥位子集。这使得DES不容易破解。

步骤 2:扩展排列—— 

回想一下,在初始排列之后,我们有两个 32 位纯文本区域,分别称为左纯文本 (LPT) 和右纯文本 (RPT)。在扩展置换过程中,RPT 从 32 位扩展为 48 位。位也被置换,因此称为扩展置换。这是因为 32 位 RPT 被分成 8 个块,每个块由 4 位组成。然后,将上一步的每个4位块扩展为对应的6位块,即每4位块增加2个位。 

此过程导致在创建输出时输入位的扩展和排列。密钥转换过程将 56 位密钥压缩为 48 位。然后扩展置换过程将 32 位 RPT 扩展为 48 位。现在 48 位密钥与 48 位 RPT 进行异或运算,得到的输出提供给下一步,即 S-Box 替换。


#include <bits/stdc++.h>

using namespace std;

string hex2bin(string s)

{

    // hexadecimal to binary conversion

    unordered_map<char, string> mp;

    mp['0'] = "0000";

    mp['1'] = "0001";

    mp['2'] = "0010";

    mp['3'] = "0011";

    mp['4'] = "0100";

    mp['5'] = "0101";

    mp['6'] = "0110";

    mp['7'] = "0111";

    mp['8'] = "1000";

    mp['9'] = "1001";

    mp['A'] = "1010";

    mp['B'] = "1011";

    mp['C'] = "1100";

    mp['D'] = "1101";

    mp['E'] = "1110";

    mp['F'] = "1111";

    string bin = "";

    for (int i = 0; i < s.size(); i++) {

        bin += mp[s[i]];

    }

    return bin;

}

string bin2hex(string s)

{

    // binary to hexadecimal conversion

    unordered_map<string, string> mp;

    mp["0000"] = "0";

    mp["0001"] = "1";

    mp["0010"] = "2";

    mp["0011"] = "3";

    mp["0100"] = "4";

    mp["0101"] = "5";

    mp["0110"] = "6";

    mp["0111"] = "7";

    mp["1000"] = "8";

    mp["1001"] = "9";

    mp["1010"] = "A";

    mp["1011"] = "B";

    mp["1100"] = "C";

    mp["1101"] = "D";

    mp["1110"] = "E";

    mp["1111"] = "F";

    string hex = "";

    for (int i = 0; i < s.length(); i += 4) {

        string ch = "";

        ch += s[i];

        ch += s[i + 1];

        ch += s[i + 2];

        ch += s[i + 3];

        hex += mp[ch];

    }

    return hex;

}

 

string permute(string k, int* arr, int n)

{

    string per = "";

    for (int i = 0; i < n; i++) {

        per += k[arr[i] - 1];

    }

    return per;

}

 

string shift_left(string k, int shifts)

{

    string s = "";

    for (int i = 0; i < shifts; i++) {

        for (int j = 1; j < 28; j++) {

            s += k[j];

        }

        s += k[0];

        k = s;

        s = "";

    }

    return k;

}

 

string xor_(string a, string b)

{

    string ans = "";

    for (int i = 0; i < a.size(); i++) {

        if (a[i] == b[i]) {

            ans += "0";

        }

        else {

            ans += "1";

        }

    }

    return ans;

}

string encrypt(string pt, vector<string> rkb, vector<string> rk)

{

    // Hexadecimal to binary

    pt = hex2bin(pt);

 

    // Initial Permutation Table

    int initial_perm[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 };

    // Initial Permutation

    pt = permute(pt, initial_perm, 64);

    cout << "After initial permutation: " << bin2hex(pt) << endl;

 

    // Splitting

    string left = pt.substr(0, 32);

    string right = pt.substr(32, 32);

    cout << "After splitting: L0=" << bin2hex(left)

         << " R0=" << bin2hex(right) << endl;

 

    // Expansion D-box Table

    int exp_d[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 };

 

    // S-box Table

    int s[8][4][16] = { { 14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,

                          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,

                          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,

                          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,

                          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,

                          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,

                          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,

                          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,

                          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 } };

 

    // Straight Permutation Table

    int per[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 };

 

    cout << endl;

    for (int i = 0; i < 16; i++) {

        // Expansion D-box

        string right_expanded = permute(right, exp_d, 48);

 

        // XOR RoundKey[i] and right_expanded

        string x = xor_(rkb[i], right_expanded);

 

        // S-boxes

        string op = "";

        for (int i = 0; i < 8; i++) {

            int row = 2 * int(x[i * 6] - '0') + int(x[i * 6 + 5] - '0');

            int col = 8 * int(x[i * 6 + 1] - '0') + 4 * int(x[i * 6 + 2] - '0') + 2 * int(x[i * 6 + 3] - '0') + int(x[i * 6 + 4] - '0');

            int val = s[i][row][col];

            op += char(val / 8 + '0');

            val = val % 8;

            op += char(val / 4 + '0');

            val = val % 4;

            op += char(val / 2 + '0');

            val = val % 2;

            op += char(val + '0');

        }

        // Straight D-box

        op = permute(op, per, 32);

 

        // XOR left and op

        x = xor_(op, left);

 

        left = x;

 

        // Swapper

        if (i != 15) {

            swap(left, right);

        }

        cout << "Round " << i + 1 << " " << bin2hex(left) << " "

             << bin2hex(right) << " " << rk[i] << endl;

    }

 

    // Combination

    string combine = left + right;

 

    // Final Permutation Table

    int final_perm[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 };

 

    // Final Permutation

    string cipher = bin2hex(permute(combine, final_perm, 64));

    return cipher;

}

int main()

{

    // pt is plain text

    string pt, key;

    /*cout<<"Enter plain text(in hexadecimal): ";

    cin>>pt;

    cout<<"Enter key(in hexadecimal): ";

    cin>>key;*/

 

    pt = "123456ABCD132536";

    key = "AABB09182736CCDD";

    // Key Generation

 

    // Hex to binary

    key = hex2bin(key);

 

    // Parity bit drop table

    int keyp[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 };

 

    // getting 56 bit key from 64 bit using the parity bits

    key = permute(key, keyp, 56); // key without parity

 

    // Number of bit shifts

    int shift_table[16] = { 1, 1, 2, 2,

                            2, 2, 2, 2,

                            1, 2, 2, 2,

                            2, 2, 2, 1 };

 

    // Key- Compression Table

    int key_comp[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 };

 

    // Splitting

    string left = key.substr(0, 28);

    string right = key.substr(28, 28);

 

    vector<string> rkb; // rkb for RoundKeys in binary

    vector<string> rk; // rk for RoundKeys in hexadecimal

    for (int i = 0; i < 16; i++) {

        // Shifting

        left = shift_left(left, shift_table[i]);

        right = shift_left(right, shift_table[i]);

 

        // Combining

        string combine = left + right;

 

        // Key Compression

        string RoundKey = permute(combine, key_comp, 48);

 

        rkb.push_back(RoundKey);

        rk.push_back(bin2hex(RoundKey));

    }

 

    cout << " Encryption: ";

    string cipher = encrypt(pt, rkb, rk);

    cout << " Cipher Text: " << cipher << endl;

 

    cout << " Decryption ";

    reverse(rkb.begin(), rkb.end());

    reverse(rk.begin(), rk.end());

    string text = encrypt(cipher, rkb, rk);

    cout << " Plain Text: " << text << endl;

}

输出: 


加密:


初始排列后:14A7D67818CA18AD

拆分后:L0=14A7D678 R0=18CA18AD


第1轮 18CA18AD 5A78E394 194CD072DE8C

第 2 轮 5A78E394 4A1210F6 4568581ABCCE

圆3 4A1210F6 B8089591 06EDA4ACF5B5

第4轮 B8089591 236779C2 DA2D032B6EE3

第 5 轮 236779C2 A15A4B87 69A629FEC913

6轮 A15A4B87 2E8F9C65 C1948E87475E

圆7 2E8F9C65 A9FC20A3 708AD2DDB3C0

圆8 A9FC20A3 308BEE97 34F822F0C66D

圆9 308BEE97 10AF9D37 84BB4473DCCC

圆形 10 10AF9D37 6CA6CB20 02765708B5BF

圆11 6CA6CB20 FF3C485F 6D5560AF7CA5

12轮 FF3C485F 22A5963B C2C1E96A4BF3

圆形 13 22A5963B 387CCDAA 99C31397C91F

圆形 14 387CCDAA BD2DD2AB 251B8BC717D0

圆15 BD2DD2AB CF26B472 3330C5D9A36D

圆形16 19BA9212 CF26B472 181C5D75C66D


密文:C0B7A8D05F3A829C


解密


初始排列后:19BA9212CF26B472

拆分后:L0=19BA9212 R0=CF26B472


第1轮CF26B472 BD2DD2AB 181C5D75C66D

第 2 轮 BD2DD2AB 387CCDAA 3330C5D9A36D

第 3 轮 387CCDAA 22A5963B 251B8BC717D0

4轮22A5963B FF3C485F 99C31397C91F

第5轮FF3C485F 6CA6CB20 C2C1E96A4BF3

圆6 6CA6CB20 10AF9D37 6D5560AF7CA5

圆7 10AF9D37 308BEE97 02765708B5BF

圆8 308BEE97 A9FC20A3 84BB4473DCCC

圆9 A9FC20A3 2E8F9C65 34F822F0C66D

圆形 10 2E8F9C65 A15A4B87 708AD2DDB3C0

第11轮 A15A4B87 236779C2 C1948E87475E

圆12 236779C2 B8089591 69A629FEC913

第13轮 B8089591 4A1210F6 DA2D032B6EE3

圆14 4A1210F6 5A78E394 06EDA4ACF5B5

第 15 轮 5A78E394 18CA18AD 4568581ABCCE

圆形 16 14A7D678 18CA18AD 194CD072DE8C


纯文本:123456ABCD132536


来源:

Host List

热点排行

hot news

TAG