Folks, I'm writing a simple cli tool to encrypt a text and decrypt based on the passed arguments. It works fine when I use only text. But It behaves strange when I pass some symbols.
MY SOURCE CODE
import argparse
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)
return key
def load_key():
"""
Loads the key named 'secret.key' from current directory
"""
return open("secret.key", "rb").read()
def encrypt_message(message):
"""
Encrypts a message
"""
key = load_key()
encoded_msg = message.encode()
f = Fernet(key)
encrypted_message = f.encrypt(encoded_msg)
with open("encrypted.txt", "wb") as encrypted_file:
encrypted_file.write(encrypted_message)
return encrypted_message
def decrypt_message(encrypted_msg):
"""
Decrypt an encrypted message
"""
key = load_key()
f = Fernet(key)
decrypted_message = f.decrypt(encrypted_msg)
return decrypted_message.decode()
def Main():
parser = argparse.ArgumentParser()
parser.add_argument("-e", "--en_crypt", help="Pass the text to encrypt as an argument")
parser.add_argument("-d", "--de_crypt", help="Pass the text to decrypt as an argument", action="store_true")
parser.add_argument("-k", "--key", help="Generate the 'secret.key' file", action="store_true")
args = parser.parse_args()
if args.en_crypt:
enc = encrypt_message(args.en_crypt)
print(enc)
if args.de_crypt:
with open("encrypted.txt", "rb") as file:
txt = file.read()
print(decrypt_message(txt))
if args.key:
result = generate_key()
print("Key Generated -> " + str(result))
if __name__ == "__main__":
Main()
MY TEST-CASE 1 - (This is successfully decrypting the text passed)
$ python3 01_crypt.py -k
Key Generated -> b'N5Ll6414I8nvcMlBytk8VwdFC4oVZZZMTCVTLpQ9big='
$ python3 01_crypt.py -e "Some Sample Text to Encrypt"
b'gAAAAABfVMU3JxZOrwLIudKLAqzq5IhivhhkyvJ6TMDxM-MmVQywo4AiZ1zGK5F5gO5JFXfHznV5zPjz6sD8qhOpIR_60Hq4_YLVIV0ztPAWBjln6reg1S0='
$ python3 01_crypt.py -d
Some Sample Text to Encrypt
MY TEST-CASE 2 - (This is not working as expected)
$ python3 01_crypt.py -k
Key Generated -> b'UDUpsIP-Ltjz8XGm-BUSwApXYE_L8eFl6rmE1yBbYW4='
$ python3 01_crypt.py -e "P@$$w0rD"
b'gAAAAABfVMX4tSIU4T1CM5Sw9jGR_O2cuIhccEM4htVTkerQD0YxWuCoUZeDWOeMIfpcP4HV7vYKmrxD22sf7yk27hGCdx0jQA=='
$ python3 01_crypt.py -d
P@4103w0rD
As per the test-case 2, My expected output should be same as the encrypted one P@$$w0rD
but instead it shows as P@4103w0rD
I'm clueless why this happen. Am I missing something important? Please advice. Thanks in Advance!
ADDITIONAL NOTE
When I try the same facility without argparse
It works as expected. Please review the code below,
from cryptography.fernet import Fernet
def key_generate():
"""
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)
return key
def load_keys():
"""
Loads the generated key named 'secret.key' from current directory
"""
return open("secret.key", "rb").read()
def encrypt_message(message):
"""
Encrypts a message
"""
key = load_keys()
encoded_msg = message.encode()
f = Fernet(key)
encrypted_message = f.encrypt(encoded_msg)
return encrypted_message
def decrypt_message(encrypted_msg):
"""
Decrypt an encrypted message
"""
key = load_keys()
f = Fernet(key)
decrypted_message = f.decrypt(encrypted_msg)
# print(type(encrypted_msg))
return decrypted_message.decode()
if __name__ == "__main__":
key_generate()
load_keys()
PLAINTEXT = "P@$$w0rD"
print("Plain Text", PLAINTEXT)
ENCRYPTED_TEXT = encrypt_message(PLAINTEXT)
print("Encrypted Text", ENCRYPTED_TEXT)
DECRYPTED_TEXT = decrypt_message(ENCRYPTED_TEXT)
print("Decrypted Text", DECRYPTED_TEXT)
OUTPUT
$python3 02_decrypt.py
Plain Text P@$$w0rD
Encrypted Text b'gAAAAABfVMfzv7H--aTCaUBdHVs05VRbFmuqpnrt-7k1NCTY9FrGMZKH8y2pkKqZsu5oxRqRgp5DzyRHZhfmA9p_cgNniWfsNw=='
Decrypted Text P@$$w0rD
The above behaviour makes me suspect, argparse
could be culprit. Please advice.
Argparse is not at fault, your usage of your shell is.
has your Unix shell substitute the current PID for
$$
(which happened to be 4103).Use single quotes to avoid the substitution.