I am new to python and I am writing a secure ftp server / client to handle basic file upload / download (but encrypted).
So that the client has a secret key, I encrypt and send a randomized 32-byte number. The client must decrypt the number, add it, re-encrypt and return it to the server. The server checks if the response is a random number + 1, and then proceeds to the connection if it is equivalent. The problem is that this works in about 90% of cases, but sometimes it fails (even when the client sends a good response).
if int.from_bytes(challenge, "big") + 1 == int.from_bytes(response, "big"): print("Good\nExpected: {0}\nReceived: {0}".format( int.from_bytes(challenge, "big") + 1, int.from_bytes(response, "big"))) else: print("Bad\nExpected: {0}\nReceived: {0}".format( int.from_bytes(challenge, "big") + 1, int.from_bytes(response, "big")))
9 times out of 10, this enters the True state, but sometimes it fails. These are examples of when he failed:
Bad Expected: 65159048323870645118410560973513118036375130115063959378348917255680432299875 Received: 65159048323870645118410560973513118036375130115063959378348917255680432299875 Bad Expected: 94602782648778784750235610259612519850690550920952731294858863927077528757933 Received: 94602782648778784750235610259612519850690550920952731294858863927077528757933
Please note that each of the above expected and received is virtually identical.
Here are some examples of successful numbers:
Good Expected: 91751260209520864629218443027060768890746721638897648279482154562044918570881 Received: 91751260209520864629218443027060768890746721638897648279482154562044918570881 Good Expected: 104504930179798203375748204555227260444250367405369759767776407892919812999121 Received: 104504930179798203375748204555227260444250367405369759767776407892919812999121
Any idea what is going on? Thank you for your time. Edit: code snippet:
Server side:
challenge = os.urandom(32) socket.send_msg(challenge, encrypt=True) response = socket.recv_msg(32, decrypt=True) if int.from_bytes(challenge, "big") + 1 != int.from_bytes(response, "big"): print("Expected: {0}\nReceived: {0}".format(int.from_bytes(challenge, "big") + 1, int.from_bytes(response, "big")))
client side:
challenge = self._socket.recv_raw(32, decrypt=True) challenge = int.from_bytes(challenge, "big") + 1 self.sckt.send_msg(challenge.to_bytes(32, "big"), encrypt=True)
Please note that I have carefully tested the encryption code and socket messaging protocol, this is not a problem.