Search code examples
pythonsocketspbkdf2

Python program crashes when trying to send data hashed with PBKDF2


I am trying to make my login system secure, and I am using PBKDF2 hashing algorithm. But every time I am launching my program and trying to send something to the server, it crashes with some strange error Process finished with exit code -1073740791 (0xC0000409) Here is the code of Send_login function:

    try:
        tcp_client = socket(AF_INET, SOCK_STREAM)
        tcp_client.connect((host_ip, server_port))
        tcp_client.sendall(('L|' + str(pbkdf2.crypt(Login.encode(), iterations=150, salt="f597beecd1f5be49cce44b7b62316669")) + '|' + str(pbkdf2.crypt(Pass.encode(), iterations=150, salt="f597beecd1f5be49cce44b7b62316669"))))
        received = tcp_client.recv(2048)
        received = received.decode("utf8")
        if received == "Auth succeed":
            print("Credentials are correct")
        else:
            print("Either credentials are incorrect or our servers are unavailable right now")
    finally:
        tcp_client.close()

PS:Send_login() is the only function that interacts with this socket


Solution

  • First and foremost, if you're a web app, use SSL. Second if you still want to encrypt messages use the cryptography module.

    import ujson as json
    import base64, zlib
    from config import config_opts
    from cryptography.fernet import Fernet
    from cryptography.hazmat.primitives import hashes
    from cryptography.hazmat.backends import default_backend
    
    SALT = config_opts['SALT']
    SALT_SIZE = config_opts['SALT_SIZE']
    SALT_OFF_SET = config_opts['SALT_OFF_SET']
    NUMBER_OF_ITERATIONS = config_opts['NUMBER_OF_ITERATIONS']
    AES_MULTIPLE = config_opts['AES_MULTIPLE']
    
    def cryptkey(password=''):
        digest = hashes.Hash(hashes.SHA256(), backend=default_backend())
        digest.update(SALT+password)
        return Fernet(base64.urlsafe_b64encode(digest.finalize()))
    
    def encrypt(meta, password=''):
        meta = json.dumps(meta)
        meta = str(zlib.compress(meta, 9))
        f = cryptkey(password)
        return base64.urlsafe_b64encode(f.encrypt(bytes(meta)))
    
    def decrypt(meta, password=''):
        meta = base64.urlsafe_b64decode(meta)
        f = cryptkey(password)
        meta = f.decrypt(bytes(meta))
        meta = zlib.decompress(meta)
        return json.loads(meta)
    
    
     try:
            tcp_client = socket(AF_INET, SOCK_STREAM)
            tcp_client.connect((host_ip, server_port))
            tcp_client.sendall(encrypt([Login.encode(), Pass.encode()]))
            received = tcp_client.recv(2048)
            received = received.decode("utf8")
            if received == "Auth succeed":
                print("Credentials are correct")
            else:
                print("Either credentials are incorrect or our servers are unavailable right now")
        finally:
            tcp_client.close()
    

    Then your backend should use the decrypt functio (and optional password). Base64 makes it more suitable for REST api communication.