Data Encryption Standard (DES) Data Encryption Standard Algorithm Description
First, the algorithm introduction
The DES algorithm is a symmetric key algorithm for encrypting 64-bit data with a 56-bit key.
There are three entrance parameters of the DES algorithm: Key, Data, Mode. Where KEY is 8 bytes a total of 64 bits, it is the working key of the DES algorithm; DATA is also 8 bytes 64 bits, which is data to be encrypted or decrypted;
Mode is working in DES, there are two types: encryption or decryption.
Second, implement steps
Conversion key
A converts 8-byte key to 64-byte strings, not enough to make 0 (or custom)
B converted into 56 bytes according to PC1
C divides the 56-byte key to the left and right parts C [0], D [0]
D cycle 16 times (i started from 1)
{
1) The number of left shift position is obtained by C [I] and D [I];
2) Reduce C [I] D [i] PC2 is simple to simplify 48-bit K [I];
}
2. Data processing
A converts 8-byte data to a 64-byte string, and it is not enough to supplement 0 (or custom)
B converts 64-byte data to two parts L [0], R [0]
C cycle 16 times (i started from 1), encrypt data with key
{
1) 32-bit R [i-1] is extended to 48-bit E [i-1] in EXP.
2) Doss or E [I-1] and K [i];
3) Divide the difference or the result into 8 6-digit parts B [8]
4) Replacement of the cycles (J starts from 1)
{
a) b [j] The first bit and 6th bits are M, as the line number of S [J]
b) b) B [J] The second to 5 bits of N, as the number of S [J]
c) Substitution with S [J] [M] [N] to replace B [J]
}
5) G combination with B [1] to B [8] to get P
6) R [i] = p xor L [i-1];
7) L [i] = r [i-1];
}
3. R [16] L [16] after combining transformation, the final result is obtained by IP_1
Third, pay attention
1. The decryption process of the DES algorithm is the same, and the difference is only the subkey key K15, the second K14 ..., the last time I use K0, and the algorithm itself does not change.
2. In the process of using the DES key Key, the application misunderstanding of the DES algorithm should be absolutely avoided, ie: 14 of the KEY's 8th, 16th, 24 ... 64 Manage KEY as a valid data bits
Fourth, achieve source code
Int des (
Unsigned char * bufferin,
Unsigned char * bufferout,
Unsigned char * key,
Long Mode)
{
// Key transform to 56 bytes (remove the check position)
Static unsigned char pc1 [56] = {
56, 48, 40, 32, 24, 16, 8,
0, 57, 49, 41, 33, 25, 17,
9, 1, 58, 50, 42, 34, 26,
18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14,
6, 61, 53, 45, 37, 29, 21,
13, 5, 60, 52, 44, 36, 28,
20, 12, 4, 27, 19, 11, 3};
// 56 byte transform to 48 bytes (data compression)
Static unsigned char pc2 [48] = {
13, 16, 10, 23, 0, 4,
2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7,
15, 6, 26, 19, 12, 1,
40, 51, 30, 36, 46, 54,
29, 39, 50, 44, 32, 47,
43, 48, 38, 55, 33, 52,
45, 41, 49, 35, 28, 31};
// 32 byte transform to 48 bytes (data expansion)
Static unsigned char exp [48] = {
31, 0, 1, 2, 3, 4,
3, 4, 5, 6, 7, 8,
7, 8, 9, 10, 11, 12,
11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20,
19, 20, 21, 22, 23, 24,
23, 24, 25, 26, 27, 28,
27, 28, 29, 30, 31, 0};
// 64-bit data IP (Initial Permutation) transformation table
Static unsigned char ip [64] = {
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,
56, 48, 40, 32, 24, 16, 8, 0,
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6};
// Data inverse replacement (Final Permutation)
Static unsigned char ip_1 [64] = {
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,
32, 0, 40, 8, 48, 16, 56, 24};
// permutation p
Static unsigned char PP [32] = {
15, 6, 19, 20,
28, 11, 27, 16,
0, 14, 22, 25,
4, 17, 30, 9,
1, 7, 23, 13,
31, 26, 2, 8,
18, 12, 29, 5,
21, 10, 3, 24};
/ * Initialize the tables * /
/ * TABLE - S1 * /
Static Unsigned Char S1 [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};
/ * TABLE - S2 * /
Static Unsigned Char S2 [4] [16] = {
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};
/ * TABLE - S3 * /
Static unsigned char s3 [4] [16] = {
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};
/ * TABLE - S4 * /
Static unsigned char s4 [4] [16] = {
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};
/ * TABLE - S5 * /
Static unsigned char s5 [4] [16] = {
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};
/ * TABLE - S6 * /
Static unsigned char s6 [4] [16] = {
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};
/ * TABLE - S7 * /
Static unsigned char s7 [4] [16] = {
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};
/ * TABLE - S8 * /
Static Unsigned Char S8 [4] [16] = {
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};
/ * Cumulative number of left shifts in key generation * /
Static unsigned char Totrot [] = {
1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28};
/ * --------------------------------- * /
// long mode = 1; // mode, 1: encryption, 2: Decryption // unsigned char bufferin [9], bufferout [9]; // 明文, cizology
/ * --------------------------------- * /
Long i, j, k;
Long Rotshift; // Key shift
// long keylen, buflen; // key length, clear text length
Unsigned char keybuf [65]; // key, key 64-byte buffer
Unsigned char keyreal [57], keys [17] [49]; // actually use 56-byte key, 48-byte key array
Unsigned char srcbuf [65], dstbuf [65]; // 明文, ciphertext 64-byte buffer
Unsigned char L [17] [33], R [17] [33], LR [65], RL [65]; // encrypt the temporary data left and right
Unsigned char e [17] [49]; // R array expansion data
Unsigned Char B [9] [7], BB [33], P [33]; // E and K Dioli buffer array
Unsigned char C [17] [29], D [17] [29], CD [57]; // 56 byte key of the left and right parts
Unsigned char TEMP1, TEMP2, M, N, X;
// 1. Transform key
// Key to 8 bytes, use 0 to make up (or custom)
// Keylen = Strlen (const char *) key);
// if (Keylen <8)
// MEMSET (Key Keylen, 0, (8-Keylen);
/ / Convert 8 byte key to 64-byte strings
For (i = 0; i <8; i )
{
J = * (Key i);
Keybuf [8 * i] = (j / 128)% 2;
Keybuf [8 * i 1] = (j / 64)% 2;
Keybuf [8 * i 2] = (j / 32)% 2;
Keybuf [8 * i 3] = (j / 16)% 2;
Keybuf [8 * i 4] = (j / 8)% 2;
Keybuf [8 * i 5] = (j / 4)% 2;
Keybuf [8 * i 6] = (j / 2)% 2;
Keybuf [8 * i 7] = (j / 1)% 2;
}
/ / According to PC1, transform into 56 bytes, remove parity block
For (i = 0; i <56; i )
{
KeyReal [i] = keybuf [pc1 [i]];
}
// divide the 56-byte key into the left and right parts C [0], D [0]
For (i = 0; i <28; i )
{
C [0] [I] = keyreal [i];
D [0] [i] = keyreal [i 28];
}
// 16 times (i started from 1)
For (i = 1; i <17; i )
{
/ / Determine the key order according to the encryption or decryption
IF (mode) // encryption
Rotshift = Totrot [I-1];
ELSE // Decryption
Rotshift = Totrot [16-i];
// 1) The number of left right position is obtained by C [I] and D [I]; for (j = 0; j <28; j )
{
C [I] [J] = C [0] [J];
D [i] [j] = d [0] [j];
}
For (j = 0; J { Temp1 = C [I] [0]; TEMP2 = D [I] [0]; For (k = 0; k <27; k ) { C [i] [k] = C [i] [k 1]; D [i] [k] = d [i] [k 1]; } C [I] [27] = TEMP1; D [i] [27] = TEMP2; } // 2) PC2 simplification of C [i] D [i] is 48-bit K [I]; For (j = 0; j <28; j ) { CD [J] = C [I] [J]; CD [J 28] = D [i] [j]; } For (j = 0; j <48; j ) { Keys [i] [j] = CD [PC2 [J]]; } } // 2. Data processing // If you are less than 8 bytes, you will make 0 (or custom) // bufflen = strlen (const char *) bufferin; // if (buflen <8) // Memset (bufferin buflen, 0, (8-buflen); / / Convert 8-byte data to 64-byte strings For (i = 0; i <8; i ) { J = * (bufferin i); SRCBUF [i * 8] = (j / 128)% 2; SRCBUF [i * 8 1] = (j / 64)% 2; SRCBUF [i * 8 2] = (j / 32)% 2; SRCBUF [i * 8 3] = (j / 16)% 2; SRCBUF [i * 8 4] = (j / 8)% 2; SRCBUF [i * 8 5] = (j / 4)% 2; SRCBUF [i * 8 6] = (j / 2)% 2; SRCBUF [i * 8 7] = (j / 1)% 2; } // Transform SRCBUF by IP For (i = 0; i <64; i ) LR [i] = srcbuf [ip [i]]; // convert 64 bytes of data to two parts L [0], R [0] For (i = 0; i <32; i ) { L [0] [i] = lr [i]; R [0] [I] = LR [i 32]; } // 16 times (I start from 1), encrypt data with key For (i = 1; i <17; i ) { // 1) 32-bit R [I-1] is extended to 48-bit E [i-1] in EXP. For (j = 0; j <48; j ) { E [i-1] [j] = r [i-1] [exp [j]]; } // 2) Doss or E [I-1] and K [I]; For (j = 0; j <48; j ) { Keys [i] [j] = keys [i] [j] ^ e [i-1] [j]; } // 3) divide the different or the result into 8 6-digit parts B [8] For (j = 0; j <8; j ) { B [J] [0] = Keys [i] [j * 6]; B [J] [1] = Keys [i] [j * 6 1]; B [J] [2] = Keys [i] [j * 6 2]; B [J] [3] = Keys [i] [j * 6 3]; B [J] [4] = Keys [i] [j * 6 4]; B [J] [5] = Keys [i] [j * 6 5]; } // 4) Replacement of the S designation (J starts from 1) For (j = 0; j <8; j ) { // a) B [J] The first and sixth bits are M, as the line number of S [J] M = 2 * b [j] [0] b [j] [5]; // b) b [j] 2nd to 5th combination is n, as the number of S [J] N = 2 * (2 * (2 * b [j] [1] b [j]) b [j] [3]) b [j] [4]; // c) Replace B by S [J] [M] [N] to replace B [J] Switch (j) { Case 0: X = S1 [M] [N]; Break; Case 1: X = S2 [M] [N]; Break; Case 2: X = S3 [M] [N]; Break; Case 3: X = S4 [M] [N]; Break; Case 4: X = S5 [M] [N]; Break; Case 5: X = S6 [M] [N]; Break; Case 6: X = S7 [M] [N]; Break; Case 7: X = S8 [M] [N]; Break; } BB [J * 4] = (x / 8)% 2; BB [J * 4 1] = (x / 4)% 2; BB [J * 4 2] = (x / 2)% 2; BB [J * 4 3] = (x / 1)% 2; } // 5) Press the P to get P to get P For (j = 0; j <32; j ) { P [j] = bb [pp [j]]; } // 6) R [i] = p xor L [i-1]; L [i] = r [i-1]; For (j = 0; j <32; j ) { R [i] [j] = p [j] ^ l [i-1] [j]; L [i] [j] = r [i-1] [j]; } } // 3. R [16] L [16] after combining transformation is changed by IP_1 to get the last result For (i = 0; i <32; i ) { RL [i] = r [16] [i]; RL [i 32] = L [16] [i]; } For (i = 0; i <64; i ) { Dstbuf [i] = rl [ip_1 [i]]; } // convert 64-byte data to 8 bytes For (i = 0; i <8; i ) { * (bufferout i) = 0x00; For (k = 0; k <7; k ) * (Bufferout i) = ((* (Bufferout i)) DSTBUF [8 * i K]) * 2; * (Bufferout i) = * (Bufferout i) Dstbuf [8 * i 7]; } Return 0; }