Detailed analysis of DES series encryption technology (2)

Detailed analysis of DES series encryption technology (2)

We mentioned in the previous article "Detailed Analysis of DES Series Encryption Technology (1)" that DES was cracked in January 1999, and an analysis report proposed some theoretical vulnerabilities in the DES algorithm. In addition, in 2001, DES As a standard, it has been replaced. Once an encryption technology is cracked, it is inevitable to be replaced. For DES, who will replace it? Today we will discuss the descendants of DES. It is 3DES and AES.

3DES (triple-DES) is a cryptographic algorithm obtained by repeating DES three times in order to increase the strength of DES, also known as TDEA (TripleDataEncryptionAlgorithm), abbreviated as 3DES, and its process is shown in the following figure:

The plaintext can be turned into the final ciphertext after 3 DES processing.Since the length of the DES key is essentially 56bit, the key length of 3DES is 168bit.

Although 3DES repeats DES three times, it can be seen from the above figure that 3DES is not performed three times of DES encryption (encryption-encryption-encryption), but encryption-decryption-encryption. This is designed by IMB , The purpose is to be compatible with ordinary DES. For example, when the three keys of 3DES are the same, 3DES is equivalent to ordinary DES. That is to say, 3DES has downward compatibility.

In the previous blog post, when we talked about DES, we said that the encryption and decryption process of DES only changes the order of the subkeys, but in fact the processing is the same. So, if all keys use the same bit sequence , Then the result is equivalent to ordinary DES.

We look at the picture just now. If Key 1 and Key 3 use the same key, and Key 2 uses a different key (that is, only two DES keys are used), this triple DES becomes DES- EDE2.EDE means Encryption-Decryption-Encryption, as shown in the figure below:

The decryption process of 3DES is exactly the opposite of the encryption process. The decryption-encryption-decryption operations are performed in the order of key 3, key 2, and key 1. The following is the process of implementing 3DES encryption/decryption in Java:

Attached code 1.javapackage org.shangzeng.cipher;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class ThreeDESTest {

    public static void main(String[] args) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        String content="Hello,ThreeDES Test!";
        String key="shangzengxueyuan2018";
        byte[] encryptResult=encryThreeDES(content,key);
        String result=convertByteToHexString(encryptResult);
        System.out.println("3DES :"+result);
        byte[] decryptResult=decryptThreeDES(encryptResult,key);
        System.out.println("3DES :"+new String(decryptResult));
    }


   /***
     *   byte 16 
     */
    public static String convertByteToHexString(byte[] byteArray){
        String result="";
        for (int i = 0; i < byteArray.length; i++) {
            int temp=byteArray[i]& 0xff;
            String tempHex= Integer.toHexString(temp);
            if(tempHex.length()<2){
                result+="0"+tempHex;
            }else{
                result+=tempHex;
            }
        }
        return result;
    }

    public static byte[] get3DESKey(String pass){
        byte[] key=new byte[24];//3DES key 24 
        byte[] temp;
        try {
            temp=pass.getBytes("UTF-8");//
            if(key.length>temp.length){
               //temp 24 , temp key 
                System.arraycopy(temp,0,key,0,temp.length);
            }else{
               //temp 24 , temp24 key 
                System.arraycopy(temp,0,key,0,key.length);
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return key;
    }

    private static final String ALGORITHM="DESede";
    public static byte[] encryThreeDES(String message,String key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        return threeDES(message.getBytes(),key,Cipher.ENCRYPT_MODE);
    }
    public static byte[] decryptThreeDES(byte[] contentArray,String key) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
        return threeDES(contentArray,key,Cipher.DECRYPT_MODE);
    }

    private static byte[] threeDES(byte[] contentArray,String key,int mode) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        SecretKey desKey=new SecretKeySpec(get3DESKey(key), ALGORITHM);
        Cipher cipher= null;
        cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(mode,desKey);
        return cipher.doFinal(contentArray);
    }
}
 

Although 3DES is more secure than DES, its processing speed is not high. Therefore, it is rarely used for new purposes except when it pays special attention to backward compatibility. Next, let's talk about AES.

AES (Advanced Encryption Standard) is also the advanced encryption standard. It is a symmetric encryption algorithm that replaces DES and becomes a new standard. Talking about this, we found that AES, like DES, is only an encryption standard, not responsible for specific encryption algorithms. DES is implemented by Feistel, while the implementation of AES is organized by NIST (National Institute of Standards and Technology, National Institute of Standards and Technology) to organize an open election campaign. The cryptographic algorithm selected by this research will become the national standard of the United States, which is ours The FIPS mentioned in the previous article. Because the conditions for participating in this election are: the cipher algorithm of the selected AES must be unconditionally free for use by the world, so although AES is a standard in the United States, it has become the same as DES. Worldwide standards.

Participants in the AES election must also submit detailed specifications of the cryptographic algorithm, implementation code written in ANSIC and Java, and evaluation of the strength of anti-cryptography. Therefore, the cryptographic algorithm submitted by the participant must be in the detailed design and program code In the case of complete disclosure, high strength is still guaranteed, so that concealed security is eliminated.

Although the AES campaign is organized by NIST, the review of cryptographic algorithms is not done by NIST. This review is done by companies and cryptographers all over the world. So participants will try to find other cryptos from all angles. The weakness of the algorithm and prove it to other participants in the review. This way is to achieve standardization through competition.

As we mentioned earlier, although 3DES is superior to DES in terms of security, its processing speed is not high. Therefore, we must consider the processing speed of the algorithm that implements AES. In addition, whether the algorithm itself Weaknesses, ease of implementation, speed of key preparation, whether it can work effectively on various platforms, such as smart cards, low-performance platforms such as 8-bit CPUs, and high-performance platforms such as workstations, are all AES selection participants need to consider Range.

From 1997, NIST began to recruit, and in 1999, 15 algorithms and 5 algorithms were shortlisted. Finally, on October 2, 2000, Rijndael defeated the crowd and was selected as the AES standard by NIST. Rijndael was selected by the Belgian cryptographer Joan Daemen The block cipher algorithm designed by Vincent Rijmen. I don't know if Rijndal is related to the names of these two cryptographers.

Let's explain in detail the encryption and decryption of Rijndael:

First of all, the packet length and key length of Rijndael can be selected in the range of 128bit to 256bit in units of 32bit. However, in the AES specification, the packet length is fixed at 128bit, and the key length is only 128, 192, and 256.

Like DES, the Rijndael algorithm is also composed of multiple rounds, except that DES uses the Feistel network as its basic structure, while Rijndael uses the SPN structure. The encryption and decryption process of one unit is shown in the following figure:

Now we analyze these four types of processing in detail:

From the above figure, we know that the unit input group of Rijndael is 128bit, which is 16 bytes. 1. you need to perform SubBytes processing on these 16 bytes. The so-called SubBytes processing can be simply understood as the value of each byte of the input is in another The replacement table has its corresponding value, and then replaces one by one according to this correspondence. As shown in the following figure:

After SubBytes, it is ShiftRows processing. This step is to shift the rows with 4 bytes as a unit to the left according to certain rules, and the number of bytes shifted in each row is different, as shown in the following figure:

Then we start the third step of processing, that is, MixColumns processing. This step is still to perform bit operations on the value in 4 bytes and turn it into another 4-byte value, similar to the SubBytes in the first step, as follows As shown in the figure:

Finally, we need to XOR the output of MixColumns with the round key, that is, AddRoundKey processing.At this point, the round of Rijndael is over.

Because all input bits in Rijndael are encrypted in one round, compared with Feistel network, the number of rounds required for encryption is reduced. And the above four methods can be performed in parallel. As for the decryption process, except for the last step AddRoundKey is the same as when encrypting, the other three processes are the inverse operations corresponding to the original steps. The following is the Java implementation of AES:

Additional code 2.javapackage org.shangzeng.testsignature;

import javax.crypto.*;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class AESTest {

    private static String convertByteToHexString(byte[] byteArray){
        String result="";
        for (int i = 0; i < byteArray.length; i++) {
            int temp=byteArray[i]& 0xff;
            String tempHex= Integer.toHexString(temp);
            if(tempHex.length()<2){
                result+="0"+tempHex;
            }else{
                result+=tempHex;
            }
        }
        return result;
    }

    static final String ALGORITHM="AES";
    static SecretKey secretKey=null;
    public static SecretKey generateKey() throws NoSuchAlgorithmException {
        if(null==secretKey){
            KeyGenerator keyGenerator=KeyGenerator.getInstance(ALGORITHM);
            SecureRandom secureRandom=new SecureRandom();
            keyGenerator.init(secureRandom);
            secretKey=keyGenerator.generateKey();
        }
        return secretKey;
    }

    public static byte[] encrypt(String content) throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchPaddingException {
        SecretKey secretKey=generateKey();
        return aes(Cipher.ENCRYPT_MODE,secretKey,content.getBytes(Charset.forName("UTF-8")));
    }

    public static String decrypt(byte[] contentArray) throws NoSuchAlgorithmException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchPaddingException, UnsupportedEncodingException {
        SecretKey secretKey=generateKey();
        byte[] resultByte= aes(Cipher.DECRYPT_MODE,secretKey,contentArray);
        return new String(resultByte,"UTF-8");
    }


    private static byte[] aes(int mode,Key key,byte[] contentArray) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher cipher=Cipher.getInstance(ALGORITHM);
        cipher.init(mode,key);
        byte[] result=cipher.doFinal(contentArray);
        return result;
    }

    public static void main(String[] args) throws InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, NoSuchPaddingException, UnsupportedEncodingException {
        String content=" , Jacob .";
        byte[] encryptResult=encrypt(content);
        String resultByHex=convertByteToHexString(encryptResult);
        String resultByUnicode=new String(encryptResult,"UTF-8");
        System.out.println(" 16 :"+resultByHex+"\n  :"+resultByUnicode);
        String decryptResult=decrypt(encryptResult);
        System.out.println(" :"+decryptResult);
    }
}
 

For Rijndael, this The nature also means that Rijndael can be deciphered by mathematical methods. Of course, this is currently only an assumption. At present, there has not been an effective attack against Rijndael, so AES implemented with Rijndael is relatively safe.