0

Hello i am trying to decrypte messages i encrypted and stored to a database. i have the encryption key stored locally and i am sure and is constant so its used for encryption and decryption of file. but nevertheless i get invalid token error.

what could i possibly be doing wrong.

error:

Exception in thread Thread-11:
Traceback (most recent call last):
  File "C:\Users\PC GAMER\Desktop\Devs\website\chat_app\website\application\lib\site-packages\cryptography\fernet.py", line 110, in _get_unverified_token_data
    data = base64.urlsafe_b64decode(token)
  File "C:\Users\PC GAMER\AppData\Local\Programs\Python\Python39\lib\base64.py", line 133, in urlsafe_b64decode
    return b64decode(s)
  File "C:\Users\PC GAMER\AppData\Local\Programs\Python\Python39\lib\base64.py", line 87, in b64decode
    return binascii.a2b_base64(s)
binascii.Error: Invalid base64-encoded string: number of data characters (201) cannot be 1 more than a multiple of 4

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\PC GAMER\AppData\Local\Programs\Python\Python39\lib\threading.py", line 954, in _bootstrap_inner
    self.run()
  File "C:\Users\PC GAMER\AppData\Local\Programs\Python\Python39\lib\threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
  File "C:\Users\PC GAMER\Desktop\Devs\website\chat_app\website\application\lib\site-packages\socketio\server.py", line 670, in _handle_event_internal
    r = server._trigger_event(data[0], namespace, sid, *data[1:])
  File "C:\Users\PC GAMER\Desktop\Devs\website\chat_app\website\application\lib\site-packages\socketio\server.py", line 694, in _trigger_event
    return self.handlers[namespace][event](*args)
  File "C:\Users\PC GAMER\Desktop\Devs\website\chat_app\website\application\lib\site-packages\flask_socketio\__init__.py", line 282, in _handler
    return self._handle_event(handler, message, namespace, sid,
  File "C:\Users\PC GAMER\Desktop\Devs\website\chat_app\website\application\lib\site-packages\flask_socketio\__init__.py", line 766, in _handle_event
    ret = handler(*args)
  File "C:\Users\PC GAMER\Desktop\Devs\website\chat_app\website\application\main.py", line 220, in on_join
    decrypted_msg = crypter.decrypt(msg.message_text.encode(), ttl=None)
  File "C:\Users\PC GAMER\Desktop\Devs\website\chat_app\website\application\lib\site-packages\cryptography\fernet.py", line 83, in decrypt
    timestamp, data = Fernet._get_unverified_token_data(token)
  File "C:\Users\PC GAMER\Desktop\Devs\website\chat_app\website\application\lib\site-packages\cryptography\fernet.py", line 112, in _get_unverified_token_data
    raise InvalidToken
cryptography.fernet.InvalidToken

code:

@socketio.on('join')
def on_join(data):
    """User joins a room"""

    username = data["username"]
    room = data["room"]
    join_room(room)
    # send messages to join room event
    messages = Message.query.filter_by(message_room=data['room']).all()
    msg_list = []

    # decrypt message content
    with open('encryption_key', 'rb') as f:
        key = f.read()
    print(key)
    crypter = Fernet(key)

    for msg in messages:
        decrypted_msg = crypter.decrypt(msg.message_text.encode(), ttl=None)
        _dict = {'message_sender': msg.message_sender, 'message_text': decrypted_msg,
                 'message_room': msg.message_room, 'message_time': msg.message_time}
        msg_list.append(_dict)
    print(msg_list)
    socketio.emit('join_room', {'data': msg_list})
    # Broadcast that new user has joined
    send({"msg": username + " has joined the " + room + " room."}, room=room)

code to generate key:

if not os.path.isfile(encrypt_file):
    key = Fernet.generate_key()
    with open('encryption_key', 'wb') as f:
        f.write(key)
else:
    with open('encryption_key', 'rb') as f:
        key = f.read()

1 Answers1

0

The error

binascii.Error: Invalid base64-encoded string: number of data characters (201) cannot be 1 more than a multiple of 4

strongly suggests that the data you're fetching from the database is not the same as what was returned from a Fernet.encrypt call (which would have been valid base64).

You should write a reduced test case that encrypts a value, stores it to the DB, then fetches it back and compares the value fetched vs the value you just stored. It is likely that there is an encoding issue occurring here.

Paul Kehrer
  • 13,466
  • 4
  • 40
  • 57