How to Encrypt and Decrypt Data in Python using Cryptography Library
In this example, we will be using symmetric encryption, which means the same key we used to encrypt data, is also usable for decryption.
The cryptography library that we use here is built on top of AES algorithm.
Encrypt Data in Python
First, we need to install the cryptography library:
pip3 install cryptography
From the cryptography library, we need to import Fernet and start generating a key — this key is required for symmetric encryption/decryption.
Generate Key
To generate a key, we call the generate_key() method:
from cryptography.fernet import Fernet def generate_key(): """ Generates a key and save it into a file """ key = Fernet.generate_key() with open("secret.key", "wb") as key_file: key_file.write(key)
We only need to execute the above method once to generate a key.
Note: You need to keep this key in a safe place. If you lose the key, you won’t be able to decrypt the data that was encrypted with this key.
Load the Key
Once we have generated a key, we need to load the key in our method in order to encrypt data:
def load_key(): """ Loads the key named `secret.key` from the current directory. """ return open("secret.key", "rb").read()
Encrypt a Message
Now, we are ready to encrypt a message. This is a three step process:
- 1 — encode the message
- 2 — initialize the Fernet class
- 3 — pass the encoded message to encrypt() method
encode the message:
message = "message I want to encrypt".encode()
initialize the Fernet class:
encrypt the message:
encrypted_message = f.encrypt(message)
Full Code Example
Below is a full working example of encrypting a message in python:
from cryptography.fernet import Fernet def generate_key(): """ Generates a key and save it into a file """ key = Fernet.generate_key() with open("secret.key", "wb") as key_file: key_file.write(key) def load_key(): """ Load the previously generated key """ return open("secret.key", "rb").read() def encrypt_message(message): """ Encrypts a message """ key = load_key() encoded_message = message.encode() f = Fernet(key) encrypted_message = f.encrypt(encoded_message) print(encrypted_message) if __name__ == "__main__": encrypt_message("encrypt this message")
b'gAAAAABesCUIAcM8M-_Ik_-I1-JD0AzLZU8A8-AJITYCp9Mc33JaHMnYmRedtwC8LLcYk9zpTqYSaDaqFUgfz-tcHZ2TQjAgKKnIWJ2ae9GDoea6tw8XeJ4='
Decrypt Data in Python
To decrypt the message, we just call the decrypt() method from the Fernet library. Remember, we also need to load the key as well, because the key is needed to decrypt the message.
from cryptography.fernet import Fernet def load_key(): """ Load the previously generated key """ return open("secret.key", "rb").read() def decrypt_message(encrypted_message): """ Decrypts an encrypted message """ key = load_key() f = Fernet(key) decrypted_message = f.decrypt(encrypted_message) print(decrypted_message.decode()) if __name__ == "__main__": decrypt_message(b'gAAAAABesCUIAcM8M-_Ik_-I1-JD0AzLZU8A8-AJITYCp9Mc33JaHMnYmRedtwC8LLcYk9zpTqYSaDaqFUgfz-tcHZ2TQjAgKKnIWJ2ae9GDoea6tw8XeJ4=')
How do I encrypt and decrypt a string in python?
I have been looking for sometime on how to encrypt and decrypt a string. But most of it is in 2.7 and anything that is using 3.2 is not letting me print it or add it to a string. So what I’m trying to do is the following:
mystring = "Hello stackoverflow!" encoded = encode(mystring,"password") print(encoded)
decoded = decode(encoded,"password") print(decoded)
Is there anyway of doing this, using python 3.X and when the string is encoded it’s still a string, not any other variable type.
It depends if you are looking for extreme security or you just whish the string not to be readable at first glance.
I don’t really need it to secury, but the more secure the better! I’d also want to keep the encoded string short aswell.
Note that what you’re doing is encoding and has very little to do with actual encryption. A cipher takes a key and produces bytes. Those are not printable, but you can encode them in Hex, Base32, Base64, etc.
9 Answers 9
I had troubles compiling all the most commonly mentioned cryptography libraries on my Windows 7 system and for Python 3.5.
This is the solution that finally worked for me.
from cryptography.fernet import Fernet key = Fernet.generate_key() #this is your "password" cipher_suite = Fernet(key) encoded_text = cipher_suite.encrypt(b"Hello stackoverflow!") decoded_text = cipher_suite.decrypt(encoded_text)
@stone, you just need to convert text to a byte stream: encoding = «utf-8» #for example pk = bytes(original_text, encoding) encoded_text = cipher_suite.encrypt(pk)
Take a look at PyCrypto. It supports Python 3.2 and does exactly what you want.
>>> from Crypto.Cipher import AES >>> obj = AES.new('This is a key123', AES.MODE_CFB, 'This is an IV456') >>> message = "The answer is no" >>> ciphertext = obj.encrypt(message) >>> ciphertext '\xd6\x83\x8dd!VT\x92\xaa`A\x05\xe0\x9b\x8b\xf1' >>> obj2 = AES.new('This is a key123', AES.MODE_CFB, 'This is an IV456') >>> obj2.decrypt(ciphertext) 'The answer is no'
If you want to encrypt a message of an arbitrary size use AES.MODE_CFB instead of AES.MODE_CBC .
When I try import it it gives me an error: >>> from Crypto.Cipher import AES Traceback (most recent call last): File «
Copying sometimes is not enough. Use python setup.py install or type pip install pycrypto in your command line. You can download pip here: lfd.uci.edu/~gohlke/pythonlibs/#pip
In case u need to encrypt a message of arbitrary size other than size n*16 byte, u can use AES.MODE_CFB instead of MODE_CBC. obj = AES.new(‘This is a key123’, AES.MODE_CFB, ‘This is an IV456’). Refer the docs at pythonhosted.org/pycrypto
I’m getting this error while encoding ‘utf-8’ codec can’t decode byte 0xa6 in position 7: invalid start byte
Python Cryptography Toolkit (pycrypto) is required
pycrypto package is outdated and has not been maintained since 2014. There is a drop-in replacement package called pycryptodome .
And the code below flawlessly works on python 3.8
from Crypto.Cipher import AES from base64 import b64encode, b64decode class Crypt: def __init__(self, salt='SlTKeYOpHygTYkP3'): self.salt = salt.encode('utf8') self.enc_dec_method = 'utf-8' def encrypt(self, str_to_enc, str_key): try: aes_obj = AES.new(str_key.encode('utf-8'), AES.MODE_CFB, self.salt) hx_enc = aes_obj.encrypt(str_to_enc.encode('utf8')) mret = b64encode(hx_enc).decode(self.enc_dec_method) return mret except ValueError as value_error: if value_error.args[0] == 'IV must be 16 bytes long': raise ValueError('Encryption Error: SALT must be 16 characters long') elif value_error.args[0] == 'AES key must be either 16, 24, or 32 bytes long': raise ValueError('Encryption Error: Encryption key must be either 16, 24, or 32 characters long') else: raise ValueError(value_error) def decrypt(self, enc_str, str_key): try: aes_obj = AES.new(str_key.encode('utf8'), AES.MODE_CFB, self.salt) str_tmp = b64decode(enc_str.encode(self.enc_dec_method)) str_dec = aes_obj.decrypt(str_tmp) mret = str_dec.decode(self.enc_dec_method) return mret except ValueError as value_error: if value_error.args[0] == 'IV must be 16 bytes long': raise ValueError('Decryption Error: SALT must be 16 characters long') elif value_error.args[0] == 'AES key must be either 16, 24, or 32 bytes long': raise ValueError('Decryption Error: Encryption key must be either 16, 24, or 32 characters long') else: raise ValueError(value_error)
test_crpt = Crypt() test_text = """Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.""" test_key = 'MyKey4TestingYnP' test_enc_text = test_crpt.encrypt(test_text, test_key) test_dec_text = test_crpt.decrypt(test_enc_text, test_key) print(f'Encrypted: Decrypted:')
Шифрование и криптография в Python
В Python не так уж много инструментов стандартной библиотеки, которые работают с шифрованием. Однако, в нашем распоряжении есть библиотеки хешинга. Давайте рассмотрим этот вопрос в данной статье, но более детально сфокусируемся на двух сторонних пакетах: PyCrypto и cryptography. Мы научимся шифровать и расшифровывать строки при помощи двух этих библиотек.
Хеширование
Если вам нужно защитить хэши или алгоритм дайджеста сообщений, то для этого прекрасно подойдет модуль стандартной библиотеки Python hashlib. Он включает в себя безопасные алгоритмы хеширования FIPS, такие как SHA1, SHA224, SHA256, SHA384, а также SHA512 и MD5. Python также поддерживает функции хеширования adler32 и crc32, но они содержатся в модуле zlib. Одно из самых популярны применений хеширования это хранение хеша пароля, вместо самого пароля. Конечно, хеш должен быть хорошим, в противном случае он может быть расшифрован.
Другой популярный случай, в котором применяется хеширование – это хеширование файла, с последующей отправкой файла и его хеша по отдельности. Получатель файла может запустить хеш в файле, чтобы убедиться в том, что файл соответствует отправленному хешу. Если это так, значит никто не менял файл, когда он был отправлен. Давайте попробуем создать хеш md5. Но оказывается, чтобы использовать хеш md5, нужно передать его строке байта, вместо обычной. Так что мы попробовали сделать это, после чего вызвали метод дайджеста, чтобы получить наш хеш. Если вы претпочитаете хешированный дайджест, мы можем сделать и это: