JAVA Implementation of the DES algorithm!

Source: Internet
Author: User

Public class desutil {
Byte [] bytekey;

Public desutil (string strkey ){
This. bytekey = strkey. getbytes ();
}

// Declare a constant byte array
Private Static final int [] IP = {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}; // 64

Private Static final int [] ip_1 = {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}; // 64

Private Static final int [] pc_1 = {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}; // 56

Private Static final int [] pc_2 = {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}; // 48

Private Static final int [] e = {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}; // 48

Private Static final int [] P = {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}; // 32

Private Static final int [] [] [] s_box = {
{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 }},
{// S_box [1]
{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 }},
{// S_box [2]
{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 }},
{// S_box [3]
{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 }},
{// S_box [4]
{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 }},
{// S_box [5]
{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 }},
{// S_box [6]
{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 }},
{// S_box [7]
{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} // s_box [8]
};

Private Static final int [] leftmove = {1, 1, 2, 2, 2, 2, 2, 1, 2, 2, 2,
2, 2, 2, 1}; // left shift position list

Private byte [] unitdes (byte [] des_key, byte [] des_data, int flag ){
// Check whether the input parameter format is correct. If an error occurs, a null value is returned)
If (des_key.length! = 8) | (des_data.length! = 8)
| (Flag! = 1) & (flag! = 0 ))){
Throw new runtimeexception ("Data Format error! ");
}

Int flags = flag;

// Binary encryption key
Int [] keydata = new int [64];

// Encrypt binary data
Int [] encryptdata = new int [64];

// The byte array after the encryption operation is completed
Byte [] encryptcode = new byte [8];

// The Key is initially converted into a two-dimensional array.
Int [] [] keyarray = new int [16] [48];
// Convert the key byte array to a binary byte array
Keydata = readdatatobirnaryintarray (des_key );
// Convert the encrypted data byte array to a binary byte array
Encryptdata = readdatatobirnaryintarray (des_data );
// The initial test key is a two-dimensional key array.
Keyinitialize (keydata, keyarray );
// Perform encryption and decryption
Encryptcode = encrypt (encryptdata, flags, keyarray );

Return encryptcode;
}

// Initial key Array
Private void keyinitialize (INT [] key, int [] [] keyarray ){
Int I;
Int J;
Int [] K0 = new int [56];

// Special Note: XXX [IP [I]-1] and other similar Transformations
For (I = 0; I <56; I ++ ){
K0 [I] = Key [pc_1 [I]-1]; // key for PC-1 Transformation
}

For (I = 0; I <16; I ++ ){
Leftbitmove (K0, leftmove [I]);

// Special Note: XXX [IP [I]-1] and other similar Transformations
For (j = 0; j <48; j ++ ){
Keyarray [I] [J] = K0 [pc_2 [J]-1]; // generates a subkey keyarray [I] [J]
}
}
}

// Perform encryption and decryption
Private byte [] encrypt (INT [] timedata, int flag, int [] [] keyarray ){
Int I;
Byte [] encrypt = new byte [8];
Int flags = flag;
Int [] M = new int [64];
Int [] mip_1 = new int [64];

// Special Note: XXX [IP [I]-1] and other similar Transformations
For (I = 0; I <64; I ++ ){
M [I] = timedata [IP [I]-1]; // plaintext IP address conversion
}

If (flags = 1) {// Encryption

For (I = 0; I <16; I ++ ){
Loopf (M, I, flags, keyarray );
}
} Else if (flags = 0) {// decrypt

For (I = 15; I>-1; I --){
Loopf (M, I, flags, keyarray );
}
}

For (I = 0; I <64; I ++ ){
Mip_1 [I] = m [ip_1 [I]-1]; // IP-1 operation
}

Getencryptresultofbytearray (mip_1, encrypt );

// Return encrypted data
Return encrypt;
}

Private int [] readdatatobirnaryintarray (byte [] intdata ){
Int I;
Int J;

// Convert data into binary data and store it in an array
Int [] intda = new int [8];

For (I = 0; I <8; I ++ ){
Intda [I] = intdata [I];

If (intda [I] <0 ){
Intda [I] ++ = 256;
Intda [I] %= 256;
}
}

Int [] intva = new int [64];

For (I = 0; I <8; I ++ ){
For (j = 0; j <8; j ++ ){
Intva [(I * 8) + 7)-J] = intda [I] % 2;
Intda [I] = intda [I]/2;
}
}

Return intva;
}

Private void leftbitmove (INT [] K, int offset ){
Int I;

// Cyclic shift operation function
Int [] C0 = new int [28];
Int [] D0 = new int [28];
Int [] C1 = new int [28];
Int [] d1 = new int [28];

For (I = 0; I <28; I ++ ){
C0 [I] = K [I];
D0 [I] = K [I + 28];
}

If (offset = 1 ){
For (I = 0; I <27; I ++) {// shifts the left of a loop
C1 [I] = C0 [I + 1];
D1 [I] = D0 [I + 1];
}

C1 [27] = C0 [0];
D1 [27] = D0 [0];
} Else if (offset = 2 ){
For (I = 0; I <26; I ++) {// shifts two places to the left of the loop
C1 [I] = C0 [I + 2];
D1 [I] = D0 [I + 2];
}

C1 [26] = C0 [0];
D1 [26] = D0 [0];
C1 [27] = C0 [1];
D1 [27] = D0 [1];
}

For (I = 0; I <28; I ++ ){
K [I] = c1 [I];
K [I + 28] = D1 [I];
}
}

Private void loopf (INT [] M, int times, int flag, int [] [] keyarray ){
Int I;
Int J;
Int [] L0 = new int [32];
Int [] R0 = new int [32];
Int [] L1 = new int [32];
Int [] R1 = new int [32];
Int [] Re = new int [48];
Int [] [] S = new int [8] [6];
Int [] sboxdata = new int [8];
Int [] svalue = new int [32];
Int [] Rp = new int [32];

For (I = 0; I <32; I ++ ){
L0 [I] = m [I]; // Initialization on the left of plaintext
R0 [I] = m [I + 32]; // initialize the right side of the plaintext
}

For (I = 0; I <48; I ++ ){
Re [I] = R0 [E [I]-1]; // extended by E transformation, from 32-bit to 48-bit
Re [I] = Re [I] + keyarray [times] [I]; // bitwise addition with keyarray [times] [I]

If (Re [I] = 2 ){
Re [I] = 0;
}
}

For (I = 0; I <8; I ++) {// 48 digits are divided into 8 groups

For (j = 0; j <6; j ++ ){
S [I] [J] = Re [(I * 6) + J];
}

// The following code goes through the S box to obtain 8 numbers
Sboxdata [I] = s_box [I] [(S [I] [0] <1) + s [I] [5] [(S [I] [1] <3)
+ (S [I] [2] <2) + (s [I] [3] <1) + s [I] [4];

// 8-digit conversion output binary
For (j = 0; j <4; j ++ ){
Svalue [(I * 4) + 3)-J] = sboxdata [I] % 2;
Sboxdata [I] = sboxdata [I]/2;
}
}

For (I = 0; I <32; I ++ ){
RP [I] = svalue [p [I]-1]; // after P Transformation
L1 [I] = R0 [I]; // move the right to the left
R1 [I] = l0 [I] + RP [I];

If (R1 [I] = 2 ){
R1 [I] = 0;
}

// Re-synthesize m and return the array m
// The left and right sides are not interchangeable during the last transformation. Two transformations are used here to achieve the same
If (flag = 0) & (Times = 0) | (flag = 1) & (Times = 15 ))){
M [I] = R1 [I];
M [I + 32] = L1 [I];
} Else {
M [I] = L1 [I];
M [I + 32] = R1 [I];
}
}
}

Private void getencryptresultofbytearray (INT [] data, byte [] value ){
Int I;
Int J;

// Convert the data in the array storing 64-bit binary data to eight integers (bytes)
For (I = 0; I <8; I ++ ){
For (j = 0; j <8; j ++ ){
Value [I] + = (data [(I <3) + J] <(7-j ));
}
}

For (I = 0; I <8; I ++ ){
Value [I] % = 256;

If (value [I]> 128 ){
Value [I]-= 255;
}
}
}

Private byte [] bytedataformat (byte [] data, int flag ){
Int Len = data. length;
Int padlen = 8-(LEN % 8 );
Int newlen = Len + padlen;
Byte [] newdata = new byte [newlen];
System. arraycopy (data, 0, newdata, 0, Len );

For (INT I = Len; I <newlen; I ++)
Newdata [I] = (byte) padlen;

Return newdata;
}

Public byte [] desencrypt (byte [] des_data, int flag ){
Byte [] format_key = bytedataformat (bytekey, flag );
Byte [] format_data = bytedataformat (des_data, flag );
Int datalen = format_data.length;
Int unitcount = datalen/8;
Byte [] result_data = new byte [datalen];

For (INT I = 0; I <unitcount; I ++ ){
Byte [] tmpkey = new byte [8];
Byte [] tmpdata = new byte [8];
System. arraycopy (format_key, 0, tmpkey, 0, 8 );
System. arraycopy (format_data, I * 8, tmpdata, 0, 8 );

Byte [] tmpresult = unitdes (tmpkey, tmpdata, flag );
System. arraycopy (tmpresult, 0, result_data, I * 8, 8 );
}

// Currently, the decryption process removes the padding generated during encryption.
Byte [] decryptbytearray = NULL;

If (flag = 0 ){
Int total_len = datalen;
Int delete_len = result_data [total_len-8-1];
Delete_len = (delete_len> = 1) & (delete_len <= 8 ))? Delete_len
: 0;
Decryptbytearray = new byte [total_len-delete_len-8];

Boolean del_flag = true;

For (int K = 0; k <delete_len; k ++ ){
If (delete_len! = Result_data [total_len-8-(k + 1)])
Del_flag = false;
}

If (del_flag = true ){
System. arraycopy (result_data, 0, decryptbytearray, 0, total_len
-Delete_len-8 );
}
}
Return (flag = 1 )? Result_data: decryptbytearray;
}

Public static void main (string [] ARGs ){
String key = "12345678 ";
String data = "don't tell anybody !! ";
Desutil = new desutil (key );
System. Err. println ("encrypted data:" + data );
// Encrypted byte ciphertext
Byte [] result = desutil. desencrypt (data. getbytes (), 1 );
System. Err. println ("encrypted data:" + new string (result ));
// Decrypt the byte-type ciphertext directly in the next sentence to restore it correctly
System. Err. println ("directly decrypts byte-type garbled characters :"
+ New string (desutil. desencrypt (result, 0) + "(correct )");

// However, when the byte ciphertext is converted to a string, and the string ciphertext is converted to a byte upon decryption, it cannot be restored correctly.
String STR = new string (result );
System. Err. println ("string-type garbled decryption :"
+ New string (desutil. desencrypt (Str. getbytes (), 0) + "(error )");
}
}
Running result:
 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.