Welcome to the next pikoTutorial !
One of the simplest ways to perform symmetric encryption in Python is to use Fernet algorithm from cryptography module. Let’s install it with command:
pip <span>install </span>cryptographypip <span>install </span>cryptographypip install cryptography
Enter fullscreen mode Exit fullscreen mode
Having cryptography module available, let’s write our first encryption script:
<span># import Fernet </span><span>from</span> <span>cryptography.fernet</span> <span>import</span> <span>Fernet</span><span># Generate a key </span><span>key</span> <span>=</span> <span>Fernet</span><span>.</span><span>generate_key</span><span>()</span><span># Create a Fernet instance providing the generated key </span><span>fernet</span> <span>=</span> <span>Fernet</span><span>(</span><span>key</span><span>)</span><span># Encrypt the data </span><span>data</span> <span>=</span> <span>b</span><span>'</span><span>Some secret data</span><span>'</span><span>encrypted_data</span> <span>=</span> <span>fernet</span><span>.</span><span>encrypt</span><span>(</span><span>data</span><span>)</span><span># Decrypt the data </span><span>decrypted_data</span> <span>=</span> <span>fernet</span><span>.</span><span>decrypt</span><span>(</span><span>encrypted_data</span><span>)</span><span>print</span><span>(</span><span>f</span><span>"</span><span>Decrypted text: </span><span>{</span><span>decrypted_data</span><span>.</span><span>decode</span><span>()</span><span>}</span><span>"</span><span>)</span><span># import Fernet </span><span>from</span> <span>cryptography.fernet</span> <span>import</span> <span>Fernet</span> <span># Generate a key </span><span>key</span> <span>=</span> <span>Fernet</span><span>.</span><span>generate_key</span><span>()</span> <span># Create a Fernet instance providing the generated key </span><span>fernet</span> <span>=</span> <span>Fernet</span><span>(</span><span>key</span><span>)</span> <span># Encrypt the data </span><span>data</span> <span>=</span> <span>b</span><span>'</span><span>Some secret data</span><span>'</span> <span>encrypted_data</span> <span>=</span> <span>fernet</span><span>.</span><span>encrypt</span><span>(</span><span>data</span><span>)</span> <span># Decrypt the data </span><span>decrypted_data</span> <span>=</span> <span>fernet</span><span>.</span><span>decrypt</span><span>(</span><span>encrypted_data</span><span>)</span> <span>print</span><span>(</span><span>f</span><span>"</span><span>Decrypted text: </span><span>{</span><span>decrypted_data</span><span>.</span><span>decode</span><span>()</span><span>}</span><span>"</span><span>)</span># import Fernet from cryptography.fernet import Fernet # Generate a key key = Fernet.generate_key() # Create a Fernet instance providing the generated key fernet = Fernet(key) # Encrypt the data data = b'Some secret data' encrypted_data = fernet.encrypt(data) # Decrypt the data decrypted_data = fernet.decrypt(encrypted_data) print(f"Decrypted text: {decrypted_data.decode()}")
Enter fullscreen mode Exit fullscreen mode
Note for beginners: the key is necessary both when encrypting and decrypting the data, so you can’t generate every time a new key. After encrypting the data, you need to store the key, but because it is something what allows you to decrypt the data, remember to store it in some secure way!
The key generated in the example above consists of random bytes. Such keys are very secure, however often you need your encryption to be password based – by password I mean some phrase which is easily understandable by humans and provided dynamically by the user as an input. Below you can find Python code showing how to get a password from the user as an input and how to turn it into the encryption key:
<span># import utility for Base64 encoding </span><span>import</span> <span>base64</span><span># import Fernet </span><span>from</span> <span>cryptography.fernet</span> <span>import</span> <span>Fernet</span><span># import getpass for secure input reading </span><span>from</span> <span>getpass</span> <span>import</span> <span>getpass</span><span># read plain text password </span><span>plain_text_password</span><span>:</span> <span>str</span> <span>=</span> <span>getpass</span><span>(</span><span>prompt</span><span>=</span><span>'</span><span>Password: </span><span>'</span><span>)</span><span># Fernet requires 32 byte key, so the password also must have 32 characters </span><span>if</span> <span>len</span><span>(</span><span>plain_text_password</span><span>)</span> <span>!=</span> <span>32</span><span>:</span><span>raise</span> <span>RuntimeError</span><span>(</span><span>f</span><span>'</span><span>Password length must be equal 32!</span><span>'</span><span>)</span><span># Encode plain text password to ASCII bytes </span><span>password_ascii</span><span>:</span> <span>bytes</span> <span>=</span> <span>plain_text_password</span><span>.</span><span>encode</span><span>(</span><span>'</span><span>ascii</span><span>'</span><span>)</span><span># Fernet requires key to be url-safe base64-encoded </span><span>key</span><span>:</span> <span>bytes</span> <span>=</span> <span>base64</span><span>.</span><span>urlsafe_b64encode</span><span>(</span><span>password_ascii</span><span>)</span><span># Create a Fernet instance providing the generated key </span><span>fernet</span> <span>=</span> <span>Fernet</span><span>(</span><span>key</span><span>)</span><span># Encrypt the data </span><span>data</span> <span>=</span> <span>b</span><span>'</span><span>Some secret data</span><span>'</span><span>encrypted_data</span> <span>=</span> <span>fernet</span><span>.</span><span>encrypt</span><span>(</span><span>data</span><span>)</span><span># Decrypt the data </span><span>decrypted_data</span> <span>=</span> <span>fernet</span><span>.</span><span>decrypt</span><span>(</span><span>encrypted_data</span><span>)</span><span>print</span><span>(</span><span>f</span><span>"</span><span>Decrypted text: </span><span>{</span><span>decrypted_data</span><span>.</span><span>decode</span><span>()</span><span>}</span><span>"</span><span>)</span><span># import utility for Base64 encoding </span><span>import</span> <span>base64</span> <span># import Fernet </span><span>from</span> <span>cryptography.fernet</span> <span>import</span> <span>Fernet</span> <span># import getpass for secure input reading </span><span>from</span> <span>getpass</span> <span>import</span> <span>getpass</span> <span># read plain text password </span><span>plain_text_password</span><span>:</span> <span>str</span> <span>=</span> <span>getpass</span><span>(</span><span>prompt</span><span>=</span><span>'</span><span>Password: </span><span>'</span><span>)</span> <span># Fernet requires 32 byte key, so the password also must have 32 characters </span><span>if</span> <span>len</span><span>(</span><span>plain_text_password</span><span>)</span> <span>!=</span> <span>32</span><span>:</span> <span>raise</span> <span>RuntimeError</span><span>(</span><span>f</span><span>'</span><span>Password length must be equal 32!</span><span>'</span><span>)</span> <span># Encode plain text password to ASCII bytes </span><span>password_ascii</span><span>:</span> <span>bytes</span> <span>=</span> <span>plain_text_password</span><span>.</span><span>encode</span><span>(</span><span>'</span><span>ascii</span><span>'</span><span>)</span> <span># Fernet requires key to be url-safe base64-encoded </span><span>key</span><span>:</span> <span>bytes</span> <span>=</span> <span>base64</span><span>.</span><span>urlsafe_b64encode</span><span>(</span><span>password_ascii</span><span>)</span> <span># Create a Fernet instance providing the generated key </span><span>fernet</span> <span>=</span> <span>Fernet</span><span>(</span><span>key</span><span>)</span> <span># Encrypt the data </span><span>data</span> <span>=</span> <span>b</span><span>'</span><span>Some secret data</span><span>'</span> <span>encrypted_data</span> <span>=</span> <span>fernet</span><span>.</span><span>encrypt</span><span>(</span><span>data</span><span>)</span> <span># Decrypt the data </span><span>decrypted_data</span> <span>=</span> <span>fernet</span><span>.</span><span>decrypt</span><span>(</span><span>encrypted_data</span><span>)</span> <span>print</span><span>(</span><span>f</span><span>"</span><span>Decrypted text: </span><span>{</span><span>decrypted_data</span><span>.</span><span>decode</span><span>()</span><span>}</span><span>"</span><span>)</span># import utility for Base64 encoding import base64 # import Fernet from cryptography.fernet import Fernet # import getpass for secure input reading from getpass import getpass # read plain text password plain_text_password: str = getpass(prompt='Password: ') # Fernet requires 32 byte key, so the password also must have 32 characters if len(plain_text_password) != 32: raise RuntimeError(f'Password length must be equal 32!') # Encode plain text password to ASCII bytes password_ascii: bytes = plain_text_password.encode('ascii') # Fernet requires key to be url-safe base64-encoded key: bytes = base64.urlsafe_b64encode(password_ascii) # Create a Fernet instance providing the generated key fernet = Fernet(key) # Encrypt the data data = b'Some secret data' encrypted_data = fernet.encrypt(data) # Decrypt the data decrypted_data = fernet.decrypt(encrypted_data) print(f"Decrypted text: {decrypted_data.decode()}")
Enter fullscreen mode Exit fullscreen mode
Note for advanced: this pikoTutorial focuses on how to use Fernet for symmetric encryption, so it simplifies the encryption key creation. In practice, when you need to create an encryption key out of user-provided password, you should use Key Derivation Function like PBKDF2HMAC.
暂无评论内容