This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

AES profiles

There are three types of AES encryption: AES-128, AES-192, and AES-256. The key length is 128bits (16 bytes), 192bits (24 bytes), and 256bits (32 bytes) respectively. Of course, the longer the key, the higher the security, encryption and decryption takes longer.

The default is AES-128, which is perfectly secure.

AES algorithm is the most common symmetric encryption algorithm (wechat small program encryption transmission is using this encryption algorithm). Symmetric encryption algorithm means that encryption and decryption use the same key. The specific encryption process is as follows:

The following is a brief introduction to the role and significance of each part:

  • Clear P

Unencrypted data.

  • The key K

The password used to encrypt plain text. In symmetric encryption algorithms, the encryption and decryption keys are the same. The key is generated through negotiation between the receiver and sender. However, the key cannot be directly transmitted over the network. Otherwise, the key is leaked. Do not leak the key. Otherwise, attackers will restore the ciphertext and steal confidential data.

  • AES encryption function

If the AES encryption function is E, C = E(K, P), where P is plaintext, K is key, and C is ciphertext. In other words, if the plaintext P and the key K are input as parameters of the encryption function, the encryption function E will output ciphertext C.

  • Cipher C

Data processed by an encryption function

  • AES decryption function

If the AES decryption function is D, P = D(K, C), where C is the ciphertext, K is the key, and P is the plaintext. In other words, if ciphertext C and key K are input as parameters of the decryption function, the decryption function will output plaintext P.

The ciphertext of the previous group and the plaintext of the current group are encrypted after xOR operations to increase the difficulty of cracking. (Not easy to attack, security is better than ECB, SSL, IPSec standard)

AES mode

AES is just a basic algorithm. There are several modes to implement AES, mainly ECB, CBC, CFB and OFB (in fact, there is also CTR).

  1. ECB is the simplest block cipher encryption mode. Before encryption, it is divided into several blocks according to the size of the encrypted block (for example, 128 bits in AES). Then, each block is encrypted separately using the same key.

  2. CBC mode (cipher-block chaining) IN CBC mode, each Cipher block to be encrypted is xor with the ciphertext of the previous Cipher block before it is encrypted. The first plaintext block is xor with a data block called an initialization vector.

  3. CFB mode (Cipher feedback) Unlike ECB and CBC modes, which encrypt only Block data, CFB can convert Block ciphers into Stream ciphers.

  4. OFB mode (output feedback: OFB is to generate the Keystream with the block encryptor first, and then xor the Keystream with the plain text stream to obtain the ciphertext stream. Decryption is to generate the Keystream with the block encryptor first, and xor the Keystream with the plain text stream to obtain the plain text. Because of the symmetry of xor operations, the flow of encryption and decryption is exactly the same.

The actual use

Use of AES in the front-end VUE project

The installation

npm install crypto-js --save-dev
Copy the code

The code examples

The ECB mode

import CryptoJS from "crypto-js";

export default {
    / / encryption
    encrypt(word, keyStr) {
        keyStr = keyStr ? keyStr : "absoietlj32fai12";
        let key = CryptoJS.enc.Utf8.parse(keyStr);
        let srcs = CryptoJS.enc.Utf8.parse(word);
        let encrypted = CryptoJS.AES.encrypt(srcs, key, {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
        });
        return encrypted.toString();
    },

    / / decryption
    decrypt(word, keyStr) {
        keyStr = keyStr ? keyStr : "absoietlj32fai12";
        var key = CryptoJS.enc.Utf8.parse(keyStr);
        var decrypt = CryptoJS.AES.decrypt(word, key, {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
        });
        returnCryptoJS.enc.Utf8.stringify(decrypt).toString(); }};Copy the code

CBC mode

import CryptoJS from "crypto-js";

export default {
    / / encryption
    encrypt(word, keyStr, ivStr) {
        keyStr = keyStr ? keyStr : "absoietlj32fai12";
        ivStr = ivStr ? ivStr : "absoietlj32fai12";
        let key = CryptoJS.enc.Utf8.parse(keyStr);
        let iv = CryptoJS.enc.Utf8.parse(ivStr);
        let srcs = CryptoJS.enc.Utf8.parse(word);
        let encrypted = CryptoJS.AES.encrypt(srcs, key, {
            iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.ZeroPadding
        });
        return encrypted.toString();
    },
    / / decryption
    decrypt(word, keyStr, ivStr) {
        keyStr = keyStr ? keyStr : "absoietlj32fai12";
        ivStr = ivStr ? ivStr : "absoietlj32fai12";
        var key = CryptoJS.enc.Utf8.parse(keyStr);
        let iv = CryptoJS.enc.Utf8.parse(ivStr);
        var decrypt = CryptoJS.AES.decrypt(word, key, {
            iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.ZeroPadding
        });
        returndecrypt.toString(CryptoJS.enc.Utf8); }};Copy the code

Use of AES in Python projects

AES Encryption and decryption tool Data block 128-bit key 16-bit IV 16-bit and equal to key Character set UTF-8 Output Base64 AES Encryption mode CBC Padding PKCS7PADDING

import base64
from Crypto.Cipher import AES

class AESHelper() :
    def __init__(self, password, iv) :
        self.password = bytes(password, encoding='utf-8')
        self.iv = bytes(iv, encoding='utf-8')

    def pkcs7padding(self, text) :
        """ Plaintext PKCS7 padding When the final call to the AES encryption method is passed in a byte array, which requires a multiple of 16, the plaintext needs to be processed :param text: content to be encrypted (plaintext) :return: """
        bs = AES.block_size  # 16
        length = len(text)
        bytes_length = len(bytes(text, encoding='utf-8'))
        # Tips: When encoding UTF-8, English takes 1 byte and Chinese takes 3 bytes
        padding_size = length if(bytes_length == length) else bytes_length
        padding = bs - padding_size % bs
        # tips: CHR (padding) see conventions with other languages, some of which use '\0'
        padding_text = chr(padding) * padding
        return text + padding_text

    def pkcs7unpadding(self, text) :
        """ Processing data populated with PKCS7 :param text: decrypted string :return: """
        length = len(text)
        unpadding = ord(text[length-1])
        return text[0:length-unpadding]

    def encrypt(self, content) :
        """ AES Encryption mode CBC Padding PKCS7 :param Key: key: param Content: encrypted content: return: """
        cipher = AES.new(self.password, AES.MODE_CBC, self.iv)
        content_padding = self.pkcs7padding(content)
        encrypt_bytes = cipher.encrypt(bytes(content_padding, encoding='utf-8'))
        result = str(base64.b64encode(encrypt_bytes), encoding='utf-8')
        return result

    def decrypt(self, content) :
        """ AES decryption mode CBC to fill pkCS7 :param Key: :param Content: :return: ""
        cipher = AES.new(self.password, AES.MODE_CBC, self.iv)
        encrypt_bytes = base64.b64decode(content)
        decrypt_bytes = cipher.decrypt(encrypt_bytes)
        result = str(decrypt_bytes, encoding='utf-8')
        result = self.pkcs7unpadding(result)
        return result

if __name__ == '__main__':
    # your password
    password = "passwordencryptd"
    # the offset
    iv = "1007217200808080"
    # Encrypt content
    source_en = 'iampassword'

    aes = AESHelper(password, iv)
    encrypt = aes.encrypt(source_en)
    decrypt = aes.decrypt(encrypt)
    print(encrypt)
Copy the code