Search code examples
pythonpycryptopython-keyringpyjks

Are there any python modules to store passwords securely in .conf/.txt files?


I am trying to read and write username and password in a secured manner. With my current implementation I am following AES-CBC encryption/decryption but storing the encrypted username the with random key in a config file is a security issue. I found an option that keystore is a better way of storing passwords. I have checked similar question but the information is not clear to me. Another option that I found is the keyring, it is working fine in windows but on Linux , I am getting following error. I have checked for the possible solutions but couldn't find one.

python keyring-test.py
Traceback (most recent call last):
  File "keyring-test.py", line 3, in <module>
    keyring.set_password(service_name="demo-service",username="admin",password="test")
  File "/usr/lib/python2.7/site-packages/keyring/core.py", line 64, in set_password
    _keyring_backend.set_password(service_name, username, password)
  File "/usr/lib/python2.7/site-packages/keyring/backends/fail.py", line 23, in get_password
    raise RuntimeError(msg)
RuntimeError: No recommended backend was available. Install the keyrings.alt package if you want to use the non-recommended backends. See README.rst for details.

Can someone suggest me any better solution or modules from python to store passwords securely?


Solution

  • My implementation whas this: I made a random string and store it to a txt file then encrypt its bytes file under a key! I use two function that i have made which the def encrypt_file takes a file encrypt their bytes and returns an encrypted file and def dencrypt_file does the opposite .

    from Crypto.Cipher import AES
    import hashlib
    import os
    import pathlib
    
    def encrypt_file(key,filein,fileout=None,IV=None):
        modes = [1,2,8,3,6,9,11,12,10,5]
        if os.path.isfile(filein):
            if IV == None:
                IV = 16 * b'\x00'
            else:
                IV = IV.encode("utf-8")
            if len(IV)==16:
                if fileout == None:
                    fileout_path = pathlib.Path(filein).parent
                    fileout_name = pathlib.Path(filein).name
                else:
                    fileout_path = pathlib.Path(fileout).parent
                    fileout_name = pathlib.Path(fileout).name
                    print (fileout_path, fileout_name )
                    if os.path.exists(fileout_path) == False:
                        print("Path Does Not Exists")
                        return
    
                encryptor = AES.new(hashlib.sha256(key.encode("utf-8")).digest(), 3, IV=IV)
                with open(filein,"rb") as f :
                    f = f.read()
                    encr_bytes = encryptor.encrypt(f)
                    file = open(str(fileout_path)+"\\"+str(fileout_name)+".enc","wb")
                    file.write(encr_bytes)
                    file.close()
                    del encryptor
            else:
                print ("IV must 16 bytes long")
                return
        else:
            print("No file path")
            return
    
    
    
    
    def dencrypt_file(key,filein,fileout=None,IV=None,TXT = False):
        if os.path.isfile(filein):
            if IV == None:
                IV = 16 * b'\x00'
            else:
                IV = IV.encode("utf-8")
            if len(IV)==16:
                if fileout == None:
                    fileout_path = pathlib.Path(filein).parent
                    fileout_name = pathlib.Path(filein).name
                    list_name = fileout_name.split(".")
                else:
                    fileout_path = pathlib.Path(fileout).parent
                    fileout_name = pathlib.Path(fileout).name
                    list_name =  fileout_name.split(".")
                    if os.path.exists(fileout_path) == False:
                        print("Path Does Not Exists")
                        return
                file_name = list_name[0] + "." + list_name[1]
                if os.path.isfile(str(fileout_path)+"\\"+str(file_name)):
                    file_name = list_name[0] + "new" +"." + list_name[1]
                    print(file_name, "OK")
                else:
                    file_name = file_name
                final_path = str(fileout_path) + "\\" +  file_name
                encryptor = AES.new(hashlib.sha256(key.encode("utf-8")).digest(), 3, IV=IV)
                with open(filein,"rb") as f :
                    if TXT == False:
                        file = open(final_path,"wb")
                        file.write(encryptor.decrypt(f.read()))
                        file.close()
                    else:
                        return encryptor.decrypt(f.read()).decode("utf-8")
            else:
                print ("IV must 16 bytes long")
                return
        else:
            print("No file path")
    return 
    

    The parameters are

    • key : your secret key
    • filein : the file that you want to encrypt
    • fileout : the output file
    • IV : the initialization Vector