0

I'm currently working on an ecrypting/decrypting program in Python using Fernet. Here's my code so far:

from cryptography.fernet import Fernet

def decrypter():
  enc_message = input("Input an encrypted string:\n")

  key = input("Input a key:\n")

  fernet = Fernet(key)

  dec_message = fernet.decrypt(enc_message).decode()
  print(dec_message)

def encrypter():
  message = input("Input a string to encrypt:\n")
  key = Fernet.generate_key()
  fernet = Fernet(key)


  enc_message = fernet.encrypt(message.encode())

  print("")
  print("Original string: ", message)
  print("")
  print("Encrypted string: ", repr(enc_message))
  print("")
  print("Key: ", repr(key))
  print("")
  dec_message = fernet.decrypt(enc_message).decode()

  print("Decrypted string: ", dec_message)

encrypter()
decrypter()

Eventually I plan on adding more quality-of-life features, but right now the encrypter function asks you for a string to encrypt, generates a key using Fernet, encrypts your string, and then prints your original string, your newly encrypted string, and the encryption key. (This is not the part that needs fixing.)

The idea of the decrypter function is that it takes an encrypted string and key from the encrypter function. It then decrypts the string using the key and prints it.

My problem is that the key is causing an error. I'm not sure if I've coded the decrypter wrong or if I'm just inputting the key in incorrectly.

My apologies if this is an easily solve-able question, I'm new to Python and couldn't really find any answers specifically for this online. Any help is much appreciated!

  • Your code would be better structured if the encryptor and decryptor are passed the key and the text to encrypt as parameters, i.e. take the input and calculate the key before calling encryptor. And the encryptor can return the encrypted data, and your calling code then passes the key and the encrypted data as parameters to the decryptor which returns the result of decrypting. This style of coding will also allow you to initially use hardcoded text to encrypt so you don’t have to provide the input every time you run your code. This also provides the way of getting the key to the decryptor :-) – DisappointedByUnaccountableMod Nov 29 '21 at 22:56
  • @balmy thank for the quick response! Do you mean I should effectively make the string and key a universal variable instead? I want to make it so that the user can theoretically use the encrypter, copy down the string and key, leave the program and then use the decrypter. – An Axolotl Nov 29 '21 at 23:07
  • By universal do you mean global? I mean make the key and string to encrypt and the encrypted strings variables outside the functions, provided to/returned by the functions. Using parameters and returns means you can use the encryptore and decyptor in more ways - the alternative of using global variables is an anti-pattern (i.e. to be avoided)that makes reuse and maintainability of your code harder. – DisappointedByUnaccountableMod Nov 30 '21 at 07:53

1 Answers1

2

Your current approach to this is to do all the input and printing within the functions dectrypter and encryptor. That means if you ever wanted to do something slightly different with the results of encrypting you'd have to rewrite those functions.

Your code would be more reusable and modular if your keep the input and printing separate for the functions which do the work, like this:

from cryptography.fernet import Fernet

def encrypter(key,plaintext):
    fernet = Fernet(key)
    enc_message = fernet.encrypt(plaintext.encode())
    return enc_message

def decrypter(key,ciphertext):
    fernet = Fernet(key)
    dec_message = fernet.decrypt(ciphertext).decode()
    return dec_message

def generatekey():
    key = Fernet.generate_key()
    return key

if __name__=="__main__":
    # comment out input() so code can be tested simply
    #plaintext = input("Input a string to encrypt:\n")
    plaintext= "A test message"

    key = generatekey()

    ciphertext = encrypter(key,plaintext)

    print("")
    print("Original string: ", plaintext)
    print("")
    print("Encrypted string: ", repr(ciphertext))
    print("")
    print("Key: ", repr(key))
    print("")

    decoded_message = decrypter(key,ciphertext)

    print("Decrypted string: ", decoded_message)

Now you could write another file which imported the above file and uses the generatekey, encrypter and decrypter, perhaps taking input from the user, without knowing or using fernet at all :-)