- cryptography · PyPI
- Welcome to pyca/cryptography — Cryptography 38.0.0.dev1 documentation
- GitHub – pyca/cryptography: cryptography is a package designed to expose cryptographic primitives and recipes to Python developers.
- How to Encrypt and Decrypt Strings in Python? – GeeksforGeeks
Installation
pip install cryptography
Introduction
cryptography
includes both high level recipes and low level interfaces to common cryptographic algorithms such as symmetric ciphers, message digests, and key derivation functions. For example, to encrypt something with cryptography
’s high level symmetric encryption recipe:
from cryptography.fernet import Fernet # Put this somewhere safe! key = Fernet.generate_key() print(key.hex()) f = Fernet(key) token = f.encrypt(b"A really secret message. Not for prying eyes.") print(token) # b'...' print(f.decrypt(token)) # b'A really secret message. Not for prying eyes.' print(token.hex())
Layout
cryptography
is broadly divided into two levels. One with safe cryptographic recipes that require little to no configuration choices. These are safe and easy to use and don’t require developers to make many decisions.
The other level is low-level cryptographic primitives. These are often dangerous and can be used incorrectly. They require making decisions and having an in-depth knowledge of the cryptographic concepts at work. Because of the potential danger in working at this level, this is referred to as the “hazardous materials” or “hazmat” layer. These live in the cryptography.hazmat
package, and their documentation will always contain an admonition at the top.
We recommend using the recipes layer whenever possible, and falling back to the hazmat layer only when necessary.
Example
สร้าง key แล้วเก็บไว้ในไฟล์ secret.key
from cryptography.fernet import Fernet # Use Fernet to generate the key file. key = Fernet.generate_key() # Store the file to disk to be accessed for en/de:crypting later. with open('secret.key', 'wb') as new_key_file: new_key_file.write(key) print(key) # print(key.decode('utf-8')) print(key.hex())
นำ key จากในไฟล์ secret.key มา encrypt ข้อความ
from cryptography.fernet import Fernet # Load the private key from a file. with open('secret.key', 'rb') as my_private_key: key = my_private_key.read() msg = "Into the valley of death, rode the 600." # Encode this as bytes to feed into the algorithm. # (Refer to Encoding types above). msg = msg.encode() # print(msg) # Instantiate the object with your key. f = Fernet(key) # Pass your bytes type message into encrypt. ciphertext = f.encrypt(msg) print(ciphertext)
นำ key จากในไฟล์ secret.key มา decrypt ข้อความ
from cryptography.fernet import Fernet # Load the private key from a file. with open('secret.key', 'rb') as my_private_key: key = my_private_key.read() # Instantiate Fernet on the recip system. f = Fernet(key) ciphertext = b'gAAAAABi9LSeFJbUUaMH3Ra-xDJkj_U_1xbs2dpzhoHQT2mTCSLIYQYBMvqYIJtrkzu1jI-IyTQCiLGCvKZfcB09Fq_wfUuAVZneIn3mg3Nz3QV4vUvT3N5xk0Iu1VfpGmdWIkrUET8_' # Decrypt the message. cleartext = f.decrypt(ciphertext) # Decode the bytes back into a string. cleartext = cleartext.decode() print(cleartext)
Using passwords with Fernet
import base64 import os from cryptography.fernet import Fernet from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC password = b"password" salt = os.urandom(16) # IV print(salt.hex()) kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), length=32, salt=salt, iterations=390000, ) key = base64.urlsafe_b64encode(kdf.derive(password)) f = Fernet(key) token = f.encrypt(b"Secret message!") print(token) # b'...' print(f.decrypt(token)) # b'Secret message!'
In this scheme, the salt has to be stored in a retrievable location in order to derive the same key from the password in the future.
The iteration count used should be adjusted to be as high as your server can tolerate. A good default is at least 480,000 iterations, which is what Django recommends as of July 2022.
Implementation
Fernet is built on top of a number of standard cryptographic primitives. Specifically it uses:
AES
inCBC
mode with a 128-bit key for encryption; usingPKCS7
padding.HMAC
usingSHA256
for authentication.- Initialization vectors are generated using
os.urandom()
.
The CBC mode requires an IV, and this IV is generated by os.urandom()
. (Python 3 Fernet encrypting same message different ways – Stack Overflow)