Как зашифровать пароль в python
Перейти к содержимому

Как зашифровать пароль в python

  • автор:

Tech Monger

In this article we will learn how to implement secure user authentication system using python werkzeug . We will store secure passwords with salted hashes and later we will verify entered user password in plaintext against it’s password hash to authenticate user.

Werkzeug is python library which contains lot of development and debugging tools for implementation of web application gateway interface( WSGI ) applications. The good part is you can use this system not only for your web applications but also for standalone python applications like desktop apps, scripts, mobile apps and so on.

Install Werkzeug with pip

Skip this step if you are using flask because flask will automatically install werkzeug as werkzeug is one of the dependency for flask .

Understanding Secure Passwords

Before we delve into the code it’s good idea to zero in on what is secure password storage.

  • Passwords will not be stored as plaintext in database.
  • Password will be stored as hash which is irreversible to plaintext. (one way hash).
  • With given hash attacker cannot guess plaintext.
  • Each user password will be hashed with salt to mitigate rainbow table attacks; Just in case if database got compromised.

Werkzeug Security Functions

There are various security functions available in the werkzeug.security but we are interested in generate_password_hash and check_password_hash .

generate_password_hash

generate_password_hash takes plaintext password, hashing method and salt length as an input to produce hashed password. By default it produces salt string with length 8.

Note that output string contains hashing method, salt and hashed password concatenated with the $ (dolor). Store hashed string as it is in your database under column hashed_password.

check_password_hash

check_password_hash takes two inputs password hash and plaintext password and returns True if hash matches actual hash of plaintext password else returns False

Project Overview:

Chitti Naidu

Here we’ll write a python program to save our passwords encrypted with a key into a JSON file.

Objectives:

  1. Encrypting plain text using Cryptography package (“pip install cryptography”).
  2. Save text into a JSON file using Json package (“pip install json”).

Summary:

It is hard to remember all the passwords we use daily either for work or for some social media accounts. We have some many applications out there to do this job. But we have a doubt on our privacy. So, we can save our passwords to a file. Still our passwords can be accessed by anyone who have access to that file. So, to encrypt the plain text and save it in a file we use python.

Program explanation:

So, getting started, first python should be installed on our system (To check for python already installed or not enter “python” for python2 or “python3” for python3 in command prompt). Next, we need to install required packages for this program.

  1. Cryptography package (pip install cryptography)
  2. Json package(pip install json)

To encrypt plain text:

We import these packages to use our own password as the key to encrypt and decrypt the text.

Here we use Symmetric encryption (encryption when key used to encrypt and decrypt the text is same). To use symmetric encryption, we create instance of Fernet class which is implementation of AES(Advanced Encryption Standard).

We also import base64 so that our key will have a url safe encoded key.

Password as key:

The above lines of code are used to convert a user defined password to a Fernet key.

Encrypt and decrypt message: To encrypt and decrypt we need a message and a key. We produced a key above from our own password and the message has to be in bytes format. We can convert a string to bytes using encode() method.

Here message is converted from string to bytes and we created an instance for class Fernet as f passing key as argument.

encrypt() and decrypt() methods are used to encrypt and decrypt string respectively. While decrypting an encrypted text we should the same key that we used to encrypt else cryptography.fernet.InvalidToken will be raised.

Saving text to JSON file: We have encrypted our passwords and need to save to a file to use whenever wanted. So, we use .json formatted file to save our passwords. JSON file stores as key-value pair similar to dictionary in python, so that we can access the passwords easily using account name or ID. We need to import json package which comes inbuilt when python installed else we can install using command pip install json.

Sometimes we have multiple accounts in a single website or application. So, we need to save account name, ID and the password associated with it.

To do this, we create three functions to read and write to json file.

  1. _read(): This function reads the data from json file and stores it in an object (obj).
  2. _write(): This function writes the data to json file.
  3. __ init__(): This function helps to create a empty json file to avoid errors while reading the contents.

_read():

As we discussed previously, json file consists data in terms of key-value pair which is dictionary in python. Object (obj) is a dictionary which contains the contents of json file. In the dictionary obj, let us consider having two different accounts for the same application with two different IDs. So, we create another dictionary within obj with account name as key. Inside this dictionary we have ID as key and password as value.

So, to get a particular password we need account name and ID. We pass them as arguments to our read function. Inside the function we use try and except blocks to handle errors occurred while reading file.

Finally, obj.get(account).get(ID) in this line, obj.get(account) returns the dictionary of that particular account and get(ID) returns password associated with that ID.

_write():

After encrypting the password, we write it to json file. Similar to read function, inside write function we first handle with errors raised during runtime due to file operations and the we begin to write contents.

So first, we read all the contents from the file and save them to an object obj(dictionary). Then we append the password accordingly. First we check whether the account is already present in the file or not, if not we directly insert the ID and password as dictionary with key as account name. Else we check whether the ID is present or not inside the dictionary for that account name. If already there we change password to new by printing “password changed.” Else we create an entity with key as ID and value as password.

Finally we save the object to the file again in the line fp.write(json.dumps(obj, indent = 4)) (indent parameter is used to represent indentation inside the json file.)

__init__() :

It is just a simple function to create an empty json file if we get error while reading the file.

Getting started with main program, first we read the account name, ID and password according to the mode we need.

Then we create Fernet key from password, create an instance of Fernet class, and if the mode is to encrypt or change password we encrypt with .encrypt() method and call write function by passing account name, ID and the encrypted password. And if mode is to decrypt we call read function passing account name and ID and pass the returned value to .decrypt() method and then print it.

Conclusion:

Congratulations, we have written a python program to encrypt our passwords and save them to a json formatted file.

Скрытие логина и пароля в коде Python

Каким образом можно зашифровать логин с паролем в самом коде? Ну или каким-либо другим способом сделать так, чтобы нельзя было бы их получить другим людям, так как сам код должен быть открытым и доступным для просмотра другими людьми.

Есть ли смысл использования в данном случае шифра Цезаря, как в данном вопросе?

Twiss's user avatar

Шифр Цезаря быстренько вскроет любой сообразительный студент вроде меня.

Мухи отдельно, котлеты отдельно: просто не пишите пароль внутри кода, и проблема будет решена сама собой. Кроме того, для подключения к какой-нибудь другой базе данных не нужно будет редактировать код, что повышает удобство. А вот где тогда писать пароль — тут уже много вариантов.

Переменная окружения

В любой «взрослой» ОС есть некие глобальные переменные, именуемые переменными окружения (переменные среды, environment variables). Можно положить пароль туда, а в питоне читать эти переменные. Как менять переменные окружения, зависит от конкретной ОС (можно детали в Википедии почитать), а в коде Python их чтение может выглядеть как-нибудь так:

В данном примере логин читается из переменной окружения MYSQL_USER , а пароль из MYSQL_PASSWORD .

Простой текстовый файл

Суть проста: пишем пароль в любом текстовом редакторе, сохраняем в текстовый файл, а потом читаем этот файл в питоне.

В данном примере логин и пароль читаются из файлов mysql_user.txt и mysql_password.txt , находящихся в текущем каталоге.

Немного пояснений, почему я читаю файлы именно так:

правила хорошего тона предписывают явно закрывать открытые файлы после их использования. Это очень удобно делать с помощью конструкции with ;

UTF-8 — самая лучшая кодировка на свете, поэтому я прописал её и советую её использовать везде и всегда. Но есть нюанс: виндовый Блокнот добавляет BOM в начале текстового файла, и для его корректной обработки питоном я прописал кодировку utf-8-sig , а не просто utf-8 ;

некоторые текстовые редакторы добавляют перенос строки в конце файла, поэтому я его удаляю с помощью rstrip() , чтоб не мешался.

Полноценный файл конфигурации

Высока вероятность, что вы захотите хранить отдельно от кода не только логин и пароль, так почему бы не завести полноценный конфиг? Можно создать, к примеру, такой файл config.ini :

А потом распарсить его в питоне:

ConfigParser — очень мощная и универсальная штука; рекомендую почитать документацию хотя бы для общего развития.

Если вы захотите выложить свой код публично на какой-нибудь GitHub, не забудьте добавить свои файлы со всеми паролями в .gitignore , чтобы случайно не опубликовать и их тоже.

Python-модуль с переменными

Можно создать Python-файл, например, local_settings.py , прописать в нём переменные с логином и паролем:

И потом обращаться к ним после импорта:

Так как local_settings.py является полноценным Python-файлом, там можно выполнять какой-нибудь произвольный код, что увеличивает гибкость в сравнении с текстовыми файлами, но в то же время открывает новые способы для выстрела в ногу, так что аккуратно.

Файл должен быть расположен так, чтобы Python его смог найти и импортировать. Он не во всех окружениях может импортировать файлы из текущего каталога, и, если простой импорт как в примере выше у вас не сработает, возможно понадобится прописать переменную окружения PYTHONPATH=. или добавить текущий каталог в список sys.path .

Кстати, все связанные с файлами способы можно комбинировать с переменными окружения. Суть такова: в переменной окружения прописываем, что читать, а Python-код потом читает указанный там файл (или импортирует указанный модуль):

Таким образом можно завести несколько файлов конфигурации и переключаться между ними с помощью переменной окружения. Подобный подход (в виде более сложном, чем я показал, но похоже) применяется, например, в популярном веб-фреймворке Django; там такая переменная окружения называется DJANGO_SETTINGS_MODULE .

Вообще не хранить ничего и запрашивать в консоли каждый раз

Вбивать пароль от базы данных каждый раз не очень удобно, но всё же тоже вариант. При этом с использованием getpass вводимый текст в консоли не отображается (даже звёздочек нету), так что никто не узнает, какой пароль вы там вводите.

Шифрование и криптография в Python

В Python не так уж много инструментов стандартной библиотеки, которые работают с шифрованием. Однако, в нашем распоряжении есть библиотеки хешинга. Давайте рассмотрим этот вопрос в данной статье, но более детально сфокусируемся на двух сторонних пакетах: PyCrypto и cryptography. Мы научимся шифровать и расшифровывать строки при помощи двух этих библиотек.

Хеширование

Если вам нужно защитить хэши или алгоритм дайджеста сообщений, то для этого прекрасно подойдет модуль стандартной библиотеки Python hashlib. Он включает в себя безопасные алгоритмы хеширования FIPS, такие как SHA1, SHA224, SHA256, SHA384, а также SHA512 и MD5. Python также поддерживает функции хеширования adler32 и crc32, но они содержатся в модуле zlib. Одно из самых популярны применений хеширования это хранение хеша пароля, вместо самого пароля. Конечно, хеш должен быть хорошим, в противном случае он может быть расшифрован.

Другой популярный случай, в котором применяется хеширование – это хеширование файла, с последующей отправкой файла и его хеша по отдельности. Получатель файла может запустить хеш в файле, чтобы убедиться в том, что файл соответствует отправленному хешу. Если это так, значит никто не менял файл, когда он был отправлен. Давайте попробуем создать хеш md5. Но оказывается, чтобы использовать хеш md5, нужно передать его строке байта, вместо обычной. Так что мы попробовали сделать это, после чего вызвали метод дайджеста, чтобы получить наш хеш. Если вы претпочитаете хешированный дайджест, мы можем сделать и это:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *