AES 256 Encryption in Python. In my last post I left off after the key expansion portion of the algorithm. The next step is to carry out the encryption of the input data. First, the input data is split into a 4x4 matrix called the state matrix. The AES encryption operations work on this matrix.
Cryptography can be defined as the practice of hiding information and includes techniques for message-integrity checking, sender/receiver identity authentication, and digital signatures. The following are the four most common types of cryptography algorithms:
- Hash functions: Also known as a one-way encryption, these have no key. A
hash
function outputs a fixed-length hash value for plaintext input, and in theory, it's impossible to recover the length or content of the plaintext. One-waycryptographic
functions are used in websites to store passwords in a manner they cannot be retrieved - Keyed hash functions: Used to build message-authentication codes (MACs); MACs are intended to prevent brute-force attacks. So, they are intentionally designed to be slow.
- Symmetric encryption: Output a ciphertext for some text input using a variable key, and you can decrypt the ciphertext using the same key. Algorithms that use the same key for both encryption and decryption are known as symmetric key algorithms.
- Public key algorithms: For public key algorithms, there are two different keys: one for encryption and the other for decryption. Users of this technology publish their public keywhile keeping their private key secret. This enables anyone to send them a message encrypted with the public key, which only the holder of the private key can decrypt. These algorithms are designed to make the search for the private key extremely difficult, even if the corresponding public key is known to an attacker.
- Python's built-in crypto functionality is currently limited to hashing. Encryption requires a third-party module like pycrypto. For example, it provides the AES algorithm which is considered state of the art for symmetric encryption. The following code will encrypt a given message using a passphrase.
- We create a new AES encryptor object with Crypto.Cipher.AES.new, and give it the encryption key and the mode. Next comes the encryption itself. Again, since the API is low-level, the encrypt method expects your input to consist of an integral number of 16-byte blocks (16 is the size of the basic AES block).
For example, for hash functions, Python provides some modules, such as hashlib
. The following script returns the md5
checksum of the file. The code for this article is available at here.
You can find the following code in the md5.py
file in the hashlib
folder in the repository:
The output of this script will be as follows:
Generate Aes 256 Key Python Online
Encrypting and decrypting information with pycrypto
When it comes to encrypting information with Python, one of the most reliable ones is the PyCrypto cryptographic library, which supports functions for block-encryption, flow-encryption, and hash-calculation.
The PyCrypto
module provides all the necessary functions for implementing strong cryptography in a Python program, including both hash functions and encryption algorithms. For example, the block ciphers supported by pycrypto
are:
- AES
- ARC2
- Blowfish
- CAST
- DES
- DES3
- IDEA
- RC5
In general, all these ciphers are used in the same way. You can use the Crypto.Cipher
package to import a specific cipher type:
You can use the new method constructor to initialize the cipher:
With this method, only the key is mandatory, and you must take into account whether the type of encryption requires that it has a specific size. The possible modes are MODE_ECB
, MODE_CBC
, MODE_CFB
, MODE_PGP
, MODE_OFB
, MODE_CTR
, and MODE_OPENPGP
.
If the MODE_CBC
or MODE_CFB
modes are used, the third parameter (Vector IV) must be initialized, which allows an initial value to be given to the cipher. Some ciphers may have optional parameters, such as AES, which can specify the block and key size with the block_size
and key_size
parameters.
In the same way as the hashlib, hash functions are also supported by pycrypto
. The use of general hash functions with pycrypto
is similar:
- Use the
Crypto.Hash
package to import a specific hash type:from Crypto.Hash import [Hash Type]
- Use the update method to set the datayouneedtoobtain the hash:
update('data')
- Use the
hexdigest()
method to generate the hash:hexdigest()
The following is the same example that you saw for obtaining the checksum of a file, in this case,you are using pycrypt instead of hashlib. You can find the following code in the hash.py
file in the pycrypto
folder:
To encrypt and decrypt data, you can use the encrypt
and decrypt
functions:
Encrypting and decrypting with the DES algorithm
DES is a block cipher, which means that the text to be encrypted is a multiple of eight, so you added spaces at the end of the text. When you decipher it, you remove it.
The following script encrypts a user and a password and, finally, simulating that it is the server that has received these credentials, decrypts, and displays this data.
You can find the following code in the Encrypt_decrypt_DES.py
file in the pycrypto
folder:
The program encrypts the data using DES, so the first thing it does is import the DES module and create an encoder with the following instruction:
The ‘mycipher’
parameter value is the encryption key. Once the cipher is created, encryption and decryption is quite simple.
Encrypting and decrypting with the AES algorithm
AES encryption needs a strong key. The stronger the key, the stronger your encryption. Your Initialization Vector needs to be 16 Bytes long. This will be generated using the random
and string
modules.
To use an encryption algorithm such as AES, you can import it from the Crypto.Cipher.AES
package. As the PyCrypto block-level encryption API is very low level, it only accepts 16-, 24-, or 32-bytes-long keys for AES-128, AES-196, and AES-256, respectively.
Also, for AES encryption using pycrypto, you need to ensure that the data is a multiple of 16 bytes in length. Pad the buffer if it is not and include the size of the data at the beginning of the output, so the receiver can decrypt it properly.
You can find the following code in the Encrypt_decrypt_AES.py
file in the pycrypto
folder:
The output of the previous script will be as follows:
File encryption with AES
AES encryption requires that each block being written be a multiple of 16 bytes in size. So, you read, encrypt, and write the data in chunks. The chunk size is required to be a multiple of 16. The following script encrypts the file provided by the parameter. You can find the following code in the aes-file-encrypt.py
file in the pycrypto
folder:
The output of the previous script is a file called file.txt.encrypted
, which contains the same content of the original file but the information is not legible. The previous script works in the way that first, you load all required modules and define the function to encrypt the file:
Also, you need to obtain your Initialization Vector. A 16-byte initialization vector is required, which is generated as follows:
Then, you can initialize the AES encryption method in the PyCrypto
module:
File decryption with AES
For decrypting, you need to reverse the preceding process using AES. You can find the following code in the aes-file-decrypt.py
file in the pycrypto
folder:
Encrypting and decrypting information with cryptography
Cryptography is a module more recent and it has better performance and security than pycrypto.
Introduction to cryptography
Cryptography is available in the pypi
repository and you can install with the pip install cryptography
command.
Cryptography includes both high-level and low-level interfaces to common cryptographic algorithms, such as symmetric ciphers, message digests, and key-derivation functions. For example, you can use symmetric encryption with the fernet package.
Symmetric encryption with the fernet
package
Fernet is an implementation of symmetric encryption and guarantees that an encrypted message cannot be manipulated or read without the key. For generating the key, you can use the generate_key()
method from the Fernet
interface.
The following code is saved in the encrypt_decrypt.py
file in the cryptography folder:
This is the output of the script:
Using passwords with the fernet package
It is possible to use passwords with Fernet. To do this, you need to run the password through a key-derivation function, such as PBKDF2HMAC. PBKDF2 (Password Based Key Derivation Function 2) is typically used for deriving a cryptographic key from a password.
Generate Aes 256 Key Python 3
In this example, you’ll this function to generate a key from a password and use that key to create the Fernet object for encrypting and decrypting data. In this case, the data to encrypt is a simple message string. You can use the verify()
method, which checks whether deriving a new key from the supplied key generates the same key as the expected key.
You can find the following code in the encrypt_decrypt_kdf.py
file in the cryptography folder:
This is the output of the script:
If you verify the key with the verify()
method, and it checks that keys do not match during the process, it launches the cryptography.exceptions.InvalidKey
exception:
Symmetric encryption with the ciphers package
The ciphers package from the cryptography
module provides a class for symmetric encryption with the cryptography.hazmat.primitives.ciphers.Cipher
class.
Generate 256 Bit Aes Key Python
Cipher objects combine an algorithm, such as AES, with a mode, such as CBC or CTR. In the following script, you can see an example of encrypting and decrypting content with AES. You can find the code in the encrypt_decrypt_AES.py
file in the cryptography folder:
This is the output of the previous script:
If you found this article interesting, you can explore José Manuel Ortega’s Mastering Python for Networking and Security to build a network and perform security operations. Mastering Python for Networking and Security will help you get the most out of the Python language to build secure and robust networks that are resilient to attacks.