How can I encrypt a login with a password in the code itself? Well, or in any other way to make it impossible for other people to get them, since the code itself must be open and available for viewing by other people.

conn = pymysql.connect( host="xxc.ru", port=3306, user="user", password="password", db="test", charset='utf8' ) 

Is there any point in using Caesar's cipher in this case, as in this question?

  • Anything that can be decrypted will be decrypted. Why should you encrypt? - andreymal
  • @andreymal so that it does not look as open as it actually is - Twiss
  • one
    Just not showing it to other eyes is the best and only reliable way to hide it;) Everybody does it, and why you can't do it the same way, it is not clear to me - andreymal
  • 3
    Store the password in a text file, read it from the file and do not show this file to anyone, hospade. Never need to write passwords right in the code! Code separately, passwords in a text file separately - and nothing needs to be encrypted. Although the option with environment variables from your answer is also an option. - andreymal
  • Since for you encryption turned out to be an optional condition, I allowed myself to reformulate your question, I hope you don’t mind - andreymal

4 answers 4

Caesar's cipher will quickly reveal any clever student like me .

Flies separately, cutlets separately: just do not write the password inside the code, and the problem will be solved by itself. In addition, to connect to any other database will not need to edit the code, which increases convenience. But then where to write a password - there are already many options.

Environment variable

In any "adult" OS there are some global variables called environment variables (environment variables). You can put the password there, and in python read these variables. How to change the environment variables depends on the specific OS (you can read the details in Wikipedia ), and in Python code reading them may look something like this:

 import os, pymysql conn = pymysql.connect( host="xxc.ru", user=os.getenv('MYSQL_USER'), password=os.getenv('MYSQL_PASSWORD'), # ... ) 

In this example, the login is read from the environment variable MYSQL_USER , and the password is from MYSQL_PASSWORD .

Plain text file

The point is simple: we write the password in any text editor, save it to a text file, and then read this file in python.

 with open('mysql_user.txt', 'r', encoding='utf-8-sig') as fp: mysql_user = fp.read().rstrip() with open('mysql_password.txt', 'r', encoding='utf-8-sig') as fp: mysql_password = fp.read().rstrip() conn = pymysql.connect( host="xxc.ru", user=mysql_user, password=mysql_password, # ... ) 

In this example, the login and password are read from the files mysql_user.txt and mysql_password.txt located in the current directory.

A few explanations why I read the files this way:

  • good tone rules explicitly close open files after they are used. This is very convenient to do with the with construction;

  • UTF-8 is the best encoding in the world, so I have prescribed it and I advise you to use it everywhere and always. But there is a nuance: Notepad adds BOM at the beginning of the text file, and for its correct processing with python I registered the encoding utf-8-sig , and not just utf-8 ;

  • Some text editors add a line rstrip() at the end of the file, so I delete it with rstrip() so as not to interfere.

Full configuration file

It is highly likely that you will want to keep separate login and password from the code, so why not have a full config? You can create, for example, such a config.ini file:

 [mysql] user = логин password = пароль 

And then parse it in python:

 import configparser, pymysql config = configparser.ConfigParser() config.read('config.ini', encoding='utf-8-sig') conn = pymysql.connect( host="xxc.ru", user=config.get('mysql', 'user'), password=config.get('mysql', 'password'), # ... ) 

ConfigParser is a very powerful and versatile thing; I recommend reading the documentation at least for general development.

If you want to put your code publicly on any GitHub, do not forget to add your files with all passwords to .gitignore , so that you don’t accidentally publish them either.

Python module with variables

You can create a Python file, for example, local_settings.py , register variables with a login and password in it:

 MYSQL_USER = 'Вася' MYSQL_PASSWORD = '123456' 

And then contact them after import:

 import local_settings as settings conn = pymysql.connect( host="xxc.ru", user=settings.MYSQL_USER, password=settings.MYSQL_PASSWORD, # ... ) 

Since local_settings.py is a full-fledged Python file, you can execute any arbitrary code there, which increases flexibility in comparison with text files, but at the same time opens up new ways for a shot in the foot, so neatly.

The file must be located so that Python can find and import it. It may not import files from the current directory in all environments, and if simple imports as in the example above do not work for you, you may need to set the environment variable PYTHONPATH=. or add the current directory to the sys.path list.

By the way, all file-related methods can be combined with environment variables. The essence is this: in the environment variable we prescribe what to read, and the Python code then reads the file specified there (or imports the specified module):

SETTINGS_MODULE=my_mysql_settings

 import os, importlib # Это значение по умолчанию на случай, если переменной окружения не будет os.environ.setdefault('SETTINGS_MODULE', 'local_settings') # Импортируем модуль, указанный в переменной окружения settings = importlib.import_module(os.getenv('SETTINGS_MODULE')) # Остальное как обычно conn = pymysql.connect( host="xxc.ru", user=settings.MYSQL_USER, password=settings.MYSQL_PASSWORD, # ... ) 

In this way, you can create several configuration files and switch between them using the environment variable. A similar approach (in a more complicated form than I have shown, but it seems) is used, for example, in the popular Django web framework; there such an environment variable is called DJANGO_SETTINGS_MODULE .

Do not store anything at all and prompt in the console every time.

It is not very convenient to drive in the database password every time, but it is also an option. In this case, using getpass input text in the console is not displayed (even there are no stars), so no one will know what password you enter there.

 import getpass, pymysql mysql_user = getpass.getpass('MySQL user> ') mysql_password = getpass.getpass('MySQL password> ') conn = pymysql.connect( host="xxc.ru", user=mysql_user, password=mysql_password, # ... ) 
  • MB, add an example of using config.py to store usernames / passwords? It will be enough to import such a module and pull out variables from it - gil9red
  • @ gil9red is basically possible, but personally this method does not seem good to me - andreymal
  • It seemed to me better than ordinary text files. Plus, it is possible to write conditions in it, like: password = "..." if DEBUG: password = "qwerty" , which is sometimes more advantageous than other options - gil9red
  • @ gil9red debug_config.ini :) - andreymal

If on Windows on your machine, then you can create two environment variables and store in them. And in the program it is obvious to read the environment variable with the name, say USERPYTHON PASSWORDSQL, and use their value so your data is hidden from the eyes of the students))

  • one
    Or store the config file in the project folder, for example, in config.py - gil9red

Use either the config file, which is stored there, where the grabbing handles do not get to someone else, or encrypt, but seriously, so that decrypting without a key is long and dreary, for example, through DES.

     import sys import keyring import getpass my_server = '192.168.0.1' def windows_credential(): # look there: cmd -> control userpasswords2 -> Advanced -> Manage passwd -> Windows Credential passwd = getpass.getpass(prompt='Please input password for account: ') keyring.set_password(my_server, getpass.getuser(), passwd) print('The Windows credential was sucessfully created for host: {} and user: {}'.format(my_server, getpass.getuser())) def get_passwd(): passwd = keyring.get_password(my_server, getpass.getuser()) if passwd is None: print('Please create windows credential for host') sys.exit(1) return passwd windows_credential() print(get_passwd()) 

    Usually encrypted passwords are stored in the database, if you do not plan to use the database in the local storage Credential manager - the storage encrypts everything for you. keyring also works with linux credentials. enter image description here