0

I am encrypting a text file using cryptography.fernet and then using the write function to write it in my file but I am getting the error write() argument must be a str not a byte. Here's the code:

from cryptography.fernet import Fernet

message = open("D:/raaghav/code/os/user/password.txt", mode='w')
messageR = open("D:/raaghav/code/os/user/password.txt", mode='r')
messageRe= messageR.read()

key = Fernet.generate_key()

fernet = Fernet(key)

encMessage = fernet.encrypt(messageRe.encode())

message.write(encMessage)

print("original string: ", message)
print('encrypted message: ', encMessage)
martineau
  • 119,623
  • 25
  • 170
  • 301
Nycelease
  • 23
  • 1
  • 6
  • ```str(encMessage)``` might help. Just replace it with where you are writing into the file –  Jun 07 '21 at 09:47
  • 1
    Open the file for writing with mode `"wb"`. Also: use `with` to close the file you're reading from before writing. Basically: 1. open 2. read 3. close 4. open 5. write 6. close – Thomas Weller Jun 07 '21 at 09:47
  • @Sujay That doesn't really work. `str(b'hello')` won't give you the string `"hello"` it'll give you `"b'hello'"`, including the `b` and embedded quote marks. Conversion to a string is via the `decode` member function. – Kemp Jun 07 '21 at 09:52
  • Bytes do not straightforwardly correspond to text until you also specify the encoding. In the case of pure 7-bit ASCII text, this mapping is trivial; but for anything else, you really do need to know the text encoding. – tripleee Jun 07 '21 at 09:52
  • @tripleee: but for encryption and decryption, we would even read a text file as binary data, wouldn't we? Encryption also works with binary files. No need to know the encoding. – Thomas Weller Jun 07 '21 at 09:56
  • Then you would read and write as binary instead. It's not clear from the question whether that's what the OP wants or needs, but it would certainly get rid of the error. – tripleee Jun 07 '21 at 09:57
  • @Nycelease: No. You would `try: ... finally: close(...)` or use `with`. – Thomas Weller Jun 07 '21 at 09:58
  • @Nycelease: and don't forget to save the key. Otherwise you won't be able to decrypt. – Thomas Weller Jun 07 '21 at 10:01
  • @Nycelease: It's quite likely that the encrypted message will be unprintable. – martineau Jun 07 '21 at 10:52

2 Answers2

0

Your output can be utf-8 encoded, so encMessage.decode('utf8') will convert your bytes object to a string.

Saving the raw binary data (the bytes object itself) can also be done by changing your file mode to 'wb'.

Seon
  • 3,332
  • 8
  • 27
  • 3
    How did you get the information that this is UTF-8 encoded? – Thomas Weller Jun 07 '21 at 09:54
  • Specified that it _can_ be utf-8 encoded. Output is base-64 encoded (see official [doc](https://cryptography.io/en/latest/fernet/#cryptography.fernet.Fernet.encrypt)) and can thus be utf-8 encoded. – Seon Jun 07 '21 at 10:21
  • 1
    @Seon: Arbitrary binary strings are valid `latin1` which can always be decoded to Unicode and then encoded back to the original string again (as pointed out in this [answer](https://stackoverflow.com/questions/22621143/serializing-binary-data-in-python/22621777#22621777) to a similar question). – martineau Jun 07 '21 at 10:47
  • That's good to know, thanks for the tip! – Seon Jun 07 '21 at 11:17
-3
str = "sample text"
byteobj = str.encode('utf-8')
print(type(byteobj)) # this the byt from the above text
retStr = byteobj.decode('utf-8')
print(retStr) # this the string changed from string from bytes
  • While this code may answer the question, providing additional context regarding why and/or how this code answers the question improves its long-term value. – Buddy Bob Jun 08 '21 at 17:46