1, What is AES?
Advanced Encryption Standard (AES) is a block encryption standard. This standard is used to replace the original DES, which has been analyzed by many parties and widely used all over the world.
So why is the original DES replaced? The reason is that it uses a 56 bit key, which is easier to crack. AES can use 128, 192, and 256 bit keys, and use 128 bit packets to encrypt and decrypt data, which is relatively much safer. Perfect encryption algorithm can not be cracked in theory unless exhaustive method is used. It is unrealistic to use the exhaustive method to crack the encrypted data with a key length of more than 128 bits, which is only possible in theory. Statistics show that even using the fastest computer in the world, it will take billions of years to exhaust the 128 bit key, let alone crack the AES algorithm with 256 bit key length.
At present, there are organizations in the world studying how to break through the thick wall of AES, but because the cracking time is too long, AES is guaranteed, but the time used is shrinking. With the increase of computer computing speed and the emergence of new algorithms, AES will only be attacked more and more violently and will not stop.
AES is now widely used in finance, online trading, wireless communication, digital storage and other fields. It has withstood the most rigorous test, but it may follow the footsteps of DES one day.
2, Brief analysis of AES encryption mode
*AES encryption is symmetric encryption. 128 192 256 represent the length of the key respectively
*The encryption method of AES will split the plaintext into different blocks for encryption. For example, if a 256 bit data is encrypted with a 128 key, it will be divided into
Plaintext 1 (128 bits) plaintext 2 (128 bits)
Encryption
Ciphertext 1 (128 bits) ciphertext 2 (128 bits)
fill:
If the plaintext is not 128 bits (16 bytes), it needs to be filled, that is, the length of an integer multiple of 16 bytes is added to a certain place of the plaintext. The same filling method needs to be used for encryption and decryption, otherwise decryption cannot succeed. The following are several filling methods
** NoPadding
No filling is required, but the plaintext must be an integer multiple of 16 bytes, which can be filled by the user himself. For filling modes other than this mode, if it is already 16 bytes of data, another 16 bytes of data will be filled
* * PKCS5Padding (default)
Fill in the end of the plaintext. The filled data is the difference between the current and 16 bytes, for example:
Plaintext not filled
1,2,3,4,5,6,7,8,9,10,11
Fill in plaintext (five bytes are missing to meet 16 bytes)
1,2,3,4,5,6,7,8,9,10,11,5,5,5,5,5
Since the last byte must be the length of the filled data when pkcs7padding / pkcs5ppadding is used, the filled data can be deleted accurately after decryption
** ISO10126Padding
Fill in at the end of the plaintext. Fill in the difference between the current and 16 bytes at the end, and fill in the random number for the remaining bytes, for example:
Plaintext not filled
1,2,3,4,5,6,7,8,9,10,11
Fill in plaintext (five bytes are missing to meet 16 bytes)
1,2,3,4,5,6,7,8,9,10,11,c,b,4,1,5
pattern
Mode is the mode that needs to be used when AES encrypts plaintext (it does not involve specific encryption methods here, but different modes in encryption steps. The same mode is also required in encryption and decryption, otherwise it will not succeed). There are five modes. The basic principle of the mode is similar, but there will be some changes in details, as follows:
* * ECB mode (default) codebook mode Electronic Codebook Book
This mode is the default, that is, the data is divided into different blocks for encryption according to the number of bits of the key. After encryption, the encrypted data are spliced together. The process is as follows:
Plaintext (64 bytes) key (16 bytes)
Plaintext 1 (16 bytes) plaintext 2 (16 bytes) plaintext 3 (16 bytes) plaintext 4 (16 bytes)
Ciphertext 1 (16 bytes) ciphertext 2 (16 bytes) ciphertext 3 (16 bytes) ciphertext 4 (16 bytes)
Ciphertext (64 bytes)
Advantages: simple, fast and parallel
Disadvantages: if the plaintext blocks are the same, the generated ciphertext blocks are the same, which will reduce the security
* * CBC mode: * * Cipher Block Chaining mode
In order to solve the problem that the ciphertext blocks of ECB mode are the same, CBC mode introduces the concept of an initial vector. The vector must be a data with the same length as the key. Before the first encryption, the initialization vector will be used for XOR operation with the first block of data, and the generated new data will be encrypted. Before encrypting the second block, The first block of ciphertext data and the second block of plaintext will be XORed before encryption, and so on. During decryption, XOR operation is also performed after decryption to generate the final plaintext. The process is as follows:
Plaintext (63 bytes) key (16 bytes) initial vector iv (16 bytes)
Plaintext 1 (16 bytes) plaintext 2 (16 bytes) plaintext 3 (16 bytes) plaintext 4 + a 0 (16 bytes)
XOR + initial vector + ciphertext 1 + ciphertext 2 + ciphertext 3
Ciphertext 1 (16 bytes) ciphertext 2 (16 bytes) ciphertext 3 (16 bytes) ciphertext 4 (16 bytes)
Ciphertext (64 bytes)
Here we need to pay attention to the following points:
1. The vector must be data equal to the length of the key
2. Because XOR operation will be performed before encryption and after decryption, our plaintext can not be completed, not a multiple of 16 bytes, and 0 will be automatically completed for XOR operation in CBC
3. During decryption, XOR operation is performed only after decryption to ensure successful data decryption
4. Due to the automatic completion, the decrypted data will also complete 0 later. Therefore, when obtaining the data, it is necessary to remove the end 0 or intercept the decrypted data according to the length of the source data
Advantages: each encryption key is different, which strengthens the security
CBC solves the disadvantages of EBC, but it also has its disadvantages:
1. Encryption cannot be performed in parallel, but decryption can be performed in parallel. The latter block can only be encrypted after the previous block is encrypted, and 0 needs to be filled in the back, so it is not suitable for streaming data (the reason for the inapplicability may be that it needs to meet the 128 bit data before encryption, so there will be no 0 completion later)
2. If the previous data is encrypted incorrectly, the subsequent data is wrong
3. Both ends need to agree on the initial vector iv at the same time
* * CFB mode: Cipher FeedBack mode
This mode only uses the encryption method. The principle is that after a numerical XOR operation, an XOR operation is performed, and the value does not change. When encrypting, if the data does not meet the bytes of a key, only save it, and then encrypt it after meeting the bytes of a key. The process is as follows:
Encryption:
Plaintext (260 bytes) iv (128 bytes)
Plaintext 1 (128 bytes) plaintext 2 (128 bytes) plaintext 3 (4 bytes)
(iv+key) XOR plaintext 1 (ciphertext 1+key) XOR plaintext 1 (ciphertext 1+key) XOR plaintext 3
Ciphertext 1 (128 bytes) ciphertext 2 (128 bytes) ciphertext 3 (4 bytes)
Decryption:
Ciphertext (260 bytes) iv (128 bytes) key (128 bytes)
Ciphertext 1 (128 bytes) ciphertext 2 (128 bytes) ciphertext 3 (4 bytes)
(iv+key) XOR ciphertext 1 (ciphertext 1+key) XOR ciphertext 2 (ciphertext 1+key) XOR ciphertext 3
Plaintext 1 (128 bytes) plaintext 2 (128 bytes) plaintext 3 (4 bytes)
Here we need to pay attention to the following points:
1. A num will be returned during encryption and decryption. This num indicates that several more numbers are needed before the last ciphertext can be used for encryption. Otherwise, the last ciphertext will always be used
2. The length of the incoming string is also required for encryption and decryption
3. Because the ciphertext is used for decryption, and the plaintext decrypted last time is not used, decryption can also be performed in parallel
4. Since the CFB mode does not need to be completed, or a complete 128 bytes can be encrypted and decrypted. In combination with the third point, it is suitable for streaming data transmission.
5. The CFB mode includes not only CFB128 (i.e. consistent with the key length), but also CFB1 and CFB8, that is, after encrypting and decrypting 1 or 8 bits, call the encryptor again to generate a new value, which can make the encryption more secure, but it will process more operations. The operation time of CFB1 is eight times that of CFB8 and 128 times that of CFB128
6. When using CFB128 or CFB8, the unit of length passed in is bytes, and the unit of CFB1 is length is bits.
7. When using CFB1 and CFB8, the num value will always be 0
Advantages: the decryption can be synchronized, and the data of non 16 byte multiples can be transmitted, which is suitable for streaming data
Of course, CFB mode also has a disadvantage. It can be decrypted in parallel when decrypting, but it cannot be encrypted in parallel when encrypting. And you also need to choose iv
* * OFB mode: Output FeedBack mode
This mode is similar to CFB, but it encrypts the data encrypted by iv or the previous iv, and the generated key performs XOR operation with the plaintext. The same method is used for decryption, using the symmetry of XOR operation for encryption and decryption. In addition, it is the same as CFB
Encryption / decryption:
CFB:
(iv+key) XOR plaintext 1 (ciphertext 1+key) XOR plaintext 1 (ciphertext 1+key) XOR plaintext 3
OFB
(iv+key) XOR plaintext 1 ((iv+key) + key) XOR plaintext 1 (((iv+key) + key) XOR plaintext 3
Advantages: like CFB, it is convenient to transfer stream data
Disadvantages: because it depends on the last encryption result, it cannot be processed in parallel. The feature is that the decryption steps are completely the same, so there will be no difference in the use method.
* * CTR mode: calculator mode Counter
The reason why OFB cannot be parallel is that it needs the result of the last iv encryption. Therefore, in CTR, we replace (iv+key) + key with (iv+1) + key, so we don't need to rely on the last encryption result. The comparison is as follows:
OFB
(iv+key) XOR plaintext 1 ((iv+key) + key) XOR plaintext 1 (((iv+key) + key) XOR plaintext 3
CTR
(iv+key) exclusive or plaintext 1 ((iv+1) + key) exclusive or plaintext 1 (((iv+1) + 1) + key) exclusive or plaintext 3
Advantages: since the encryption and decryption can be parallel, the encryption and decryption speed of CTR mode is also very fast
Disadvantages: the acquisition of iv+1 is relatively responsible, and it is necessary to obtain instantaneous iv
3, Two examples are provided
1. java mysql general aes encryption algorithm
General aes encryption, usage scenario, when inserting data, use java to encrypt the data. When querying, decrypt through sql without taking it out and then traversing decryption
Note: to_base64 is only applicable to mysql5 After 6, the previous one does not have this function, which is not applicable. HEX and UNHEX can be used. Of course, java should be decrypted with the corresponding method
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; /** * java Decrypt AES-128-ECB encryption using AES encryption * Common with mysql database aes encryption algorithm * Database aes encryption and decryption * -- encryption * SELECT to_base64(AES_ENCRYPT('www.gowhere.so','jkl;POIU1234++==')); * -- decrypt * SELECT AES_DECRYPT(from_base64('Oa1NPBSarXrPH8wqSRhh3g=='),'jkl;POIU1234++=='); * @author 836508 * */ public class MyAESUtil { // encryption public static String Encrypt(String sSrc, String sKey) throws Exception { if (sKey == null) { System.out.print("Key Empty null"); return null; } // Determine whether the Key is 16 bits if (sKey.length() != 16) { System.out.print("Key Length is not 16 bits"); return null; } byte[] raw = sKey.getBytes("utf-8"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");//"Algorithm / mode / complement mode" cipher.init(Cipher.ENCRYPT_MODE, skeySpec); byte[] encrypted = cipher.doFinal(sSrc.getBytes("utf-8")); return new BASE64Encoder().encode(encrypted);//BASE64 is used as transcoding function here, and can play the role of twice encryption at the same time. } // decrypt public static String Decrypt(String sSrc, String sKey) throws Exception { try { // Judge whether the Key is correct if (sKey == null) { System.out.print("Key Empty null"); return null; } // Determine whether the Key is 16 bits if (sKey.length() != 16) { System.out.print("Key Length is not 16 bits"); return null; } byte[] raw = sKey.getBytes("utf-8"); SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, skeySpec); byte[] encrypted1 = new BASE64Decoder().decodeBuffer(sSrc);//Decrypt with base64 first try { byte[] original = cipher.doFinal(encrypted1); String originalString = new String(original,"utf-8"); return originalString; } catch (Exception e) { System.out.println(e.toString()); return null; } } catch (Exception ex) { System.out.println(ex.toString()); return null; } } public static void main(String[] args) throws Exception { /* * AES-128-ECB encryption mode is used here, and the key needs to be 16 bits. */ String cKey = "jkl;POIU1234++=="; // A string that needs to be encrypted String cSrc = "www.gowhere.so"; System.out.println(cSrc); // encryption String enString = MyAESUtil.Encrypt(cSrc, cKey); System.out.println("The encrypted string is:" + enString); // decrypt String DeString = MyAESUtil.Decrypt(enString, cKey); System.out.println("The decrypted string is:" + DeString); } }
2. java # AES-128-CBC encryption mode
package com.zhongzhi.utils; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; /** * @Classname ZzSecurityHelper * @Description TODO * @Date 2019/6/24 16:50 * @Created by whd */ public class ZzSecurityHelper { /* * The key for encryption can be composed of 26 letters and numbers. AES-128-CBC encryption mode is used, and the key needs to be 16 bits. */ private static final String key="hj7x89H$yuBI0456"; private static final String iv ="NIfb&95GUY86Gfgh"; /** * @author miracle.qu * @Description AES Algorithm encryption plaintext * @param data Plaintext * @param key Key, length 16 * @param iv Offset, length 16 * @return ciphertext */ public static String encryptAES(String data) throws Exception { try { Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); int blockSize = cipher.getBlockSize(); byte[] dataBytes = data.getBytes(); int plaintextLength = dataBytes.length; if (plaintextLength % blockSize != 0) { plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize)); } byte[] plaintext = new byte[plaintextLength]; System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length); SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); // CBC mode requires a vector iv, which can increase the strength of the encryption algorithm cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); byte[] encrypted = cipher.doFinal(plaintext); return ZzSecurityHelper.encode(encrypted).trim(); // BASE64 transcodes. } catch (Exception e) { e.printStackTrace(); return null; } } /** * @author miracle.qu * @Description AES Algorithm decrypts ciphertext * @param data ciphertext * @param key Key, length 16 * @param iv Offset, length 16 * @return Plaintext */ public static String decryptAES(String data) throws Exception { try { byte[] encrypted1 = ZzSecurityHelper.decode(data);//Decrypt with base64 first Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES"); IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes()); cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); byte[] original = cipher.doFinal(encrypted1); String originalString = new String(original); return originalString.trim(); } catch (Exception e) { e.printStackTrace(); return null; } } /** * code * @param byteArray * @return */ public static String encode(byte[] byteArray) { return new String(new Base64().encode(byteArray)); } /** * decode * @param base64EncodedString * @return */ public static byte[] decode(String base64EncodedString) { return new Base64().decode(base64EncodedString); } }