AES encryption algorithm

Advanced Encryption Standard (AES) is a symmetric Encryption algorithm (also called shared key). A symmetric Encryption algorithm means that both Encryption and decryption use the same key (the key and secret key are synonyms). Generally speaking, the symmetric Encryption algorithm is more efficient than the asymmetric Encryption algorithm. It is used to replace Data Encryption Standard (DES). AES has three key points: key, padding, and mode.

  • The key
    • The key can be divided into 128 bits (16 bytes), 192 bits (24 bytes), and 256 bits (32 bytes). The larger the number of bits, the greater the computation of decryption and encryption, and the more secure the encryption is. Therefore, 192 bits can be used in a compromise to balance efficiency and security.
  • fill
    • Fill: During encryption, data is divided into multiple plaintext blocks according to a group of 128 bits (16 bytes), and the plaintext blocks are encrypted respectively. Of course, encryption and decryption must be the same as the filling, otherwise it cannot be decrypted.
    • NoPadding
      • No padding, but the plaintext must be a multiple of 128 bits; If NoPadding is used, the program populates the plaintext preprocessing to a 16-byte integer multiple.
    • PKCS5Padding (default)
      • If the plaintext block is less than 128 bits, the corresponding number of characters is supplemented and the value of the characters is equal to the number of missing bytes. Such as clear text: {1, 2, 3, 4, 5, a, b, c, d, e}, lack of 6 bytes, completion as {1, 2, 3, 4, 5, a, b, c, d, e, 6,6,6,6,6,6}
    • ISO10126Padding
      • If the plaintext block is less than 16 bytes, the corresponding number of characters are filled in, and the value of the last character is equal to the number of missing bytes, and the other characters are filled in with random numbers; Such as clear text: {1, 2, 3, 4, 5, a, b, c, d, e}, lack of 6 bytes, likely completion for {1, 2, 3, 4, 5, a, b, c, d, e, 5 c, 3, G, $, 6}
  • model
    • Patterns, as mentioned earlier, divide data into groups of plaintext when encryption is done.
    • ECB
      • ECB (default Electronic Codebook mode) is each group encrypted and spliced, there is no relationship between the groups, can be calculated in parallel;
    • CBC
      • CBC (Cipher Block Chaining mode, default). The second group depends on the results of the first group, and the third group depends on the results of the second group. Only after the encryption of the previous group is complete, the next group can be encrypted, and so on. Unlike the ECB, the CBC has initial vectors that are evaluated before the plaintext and then evaluated against the key.

Note that the “key” we usually refer to is not the real key, but the “seed” that produces the key.

For example,

Ok, let’s experiment with AES algorithm in Java. AES algorithm is under javax.crypto package

The ECB mode

Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
String key = "aaaaaaaaaaaaaaaa";
 SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8),"AES");
 cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec);
 String content = "Hello";
 byte[] encryptBytes = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));

 cipher.init(Cipher.DECRYPT_MODE,secretKeySpec);
 byte[] plaintextBytes = cipher.doFinal(encryptBytes);
 String plaintext = new String(plaintextBytes, StandardCharsets.UTF_8);
 log.info("After decryption :{}",plaintext);
Copy the code

CBC mode

CBC mode must use initial vectors

String seed = "aaaaaaaaaaaaaaaa";
//CBC has an offset
IvParameterSpec ivspec = new IvParameterSpec(seed.getBytes(StandardCharsets.UTF_8));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(seed.getBytes(StandardCharsets.UTF_8),"AES");
cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,ivspec);
String content = "You";
byte[] encryptBytes = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));
byte[] encryptedBase64 = Base64.getEncoder().encode(encryptBytes);
log.info("Encrypted :{}".new String(encryptedBase64, StandardCharsets.UTF_8));
byte[] decode = Base64.getDecoder().decode(encryptedBase64);

cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,ivspec);
byte[] plaintextBytes = cipher.doFinal(decode);
String plaintext = new String(plaintextBytes, StandardCharsets.UTF_8);
log.info("After decryption :{}",plaintext);
Copy the code

Don’t fill

These two examples using the filling, if you are using is not filled, then you need to clear text pretreatment, ensure that clear is 16 bytes integer times, usually it is proclaimed in writing into a byte array, will fill an array of bytes for 16 times, swallow the value is 0, 0 corresponding is no character in the ASCII, when decoding so also do not need special treatment. Such as

 Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        int blockSize = cipher.getBlockSize();
        byte[] dataBytes;
		try {
			dataBytes = data.getBytes("UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e);
		}
        int plaintextLength = dataBytes.length;
        // The data length must be a multiple of 16
        if(plaintextLength % blockSize ! =0) {
            plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
        }
        byte[] plaintext = new byte[plaintextLength];
        // the byte array complement is a multiple of 16, the complement position is 0,0 in ASCII does not correspond to the character, so there is no special processing in decoding;
        System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
Copy the code

Common mistakes

java.security.InvalidKeyException: Illegal key size or default parameters

The AES algorithm provided by the default JDK only supports 128 bits, and will throw this exception if it exceeds 128 bits. According to Stack Overflow, starting with JDK8 Update 161, there is no limit to the length, so if you encounter this problem, Update the JDK.

reference

Programmer Xiao Hui speaks AES