| 10 | |
| 11 | # Encrypt plain text using a password |
| 12 | def encrypt(plain_text, password): |
| 13 | if not password: |
| 14 | raise ValueError("Password cannot be empty.") |
| 15 | |
| 16 | # Generate a random salt and derive a 256-bit key |
| 17 | salt = get_random_bytes(AES.block_size) |
| 18 | private_key = hashlib.scrypt( |
| 19 | password.encode(), salt=salt, n=2**14, r=8, p=1, dklen=32 |
| 20 | ) |
| 21 | # Create AES cipher and encrypt the message |
| 22 | cipher_config = AES.new(private_key, AES.MODE_GCM) |
| 23 | cipher_text, tag = cipher_config.encrypt_and_digest(bytes(plain_text, "utf-8")) |
| 24 | # Return all parts needed for decryption as base64 strings |
| 25 | return { |
| 26 | "cipher_text": b64encode(cipher_text).decode("utf-8"), |
| 27 | "salt": b64encode(salt).decode("utf-8"), |
| 28 | "nonce": b64encode(cipher_config.nonce).decode("utf-8"), |
| 29 | "tag": b64encode(tag).decode("utf-8"), |
| 30 | } |
| 31 | |
| 32 | |
| 33 | # Decrypt an encrypted dictionary back to plain text |