Защита реквизитов с Python
"Конфиденциальность — это не только право, это основа свободы." В эпоху цифровых технологий, когда данные становятся всё более ценным ресурсом, защита личной информации приобретает критическое значение. В этой статье я расскажу, как работать с конфиденциальными реквизитами в Python проекте.
load_dotenv
Первый способ - использовать функцию load_dotenv из модуля dotenv. Она позволяет считать строки вида ключ=значение из файла и загрузить их в переменные окружения с именем ключа. Обычно таким образом задаются конфиденциальные данные, как пароли, ключи API, которые не следует хранить в коде и тем более заливать в репозиторий.
Отмечу, что этот способ подойдет, если злоумышленник не имеет доступ к локальным файлам, так как пароль хранится в открытом виде. Продемонстрируем работу на практике. Сначала установим модуль python-dotenv и создадим файл:
!pip install python-dotenv -q !mkdir pers !printf ''' USER="user"\n\ PSWD="1pswd1" ''' > pers/.env !cat .env
Теперь вызовем load_dotenv с указанием пути к файлу:
from dotenv import load_dotenv load_dotenv('pers/.env')
После этого переменные из файла доступны через окружение:
import os os.environ['USER'], os.environ['PSWD']
Если все равно страшно хранить реквизиты в открытом файле, можно немного усложнить и, например, хранить часть пароля в файле, а часть добавлять из кода (но это все равно не безопасное решение). В функции ниже прописано такое поведение - при отсутствии создается файл с реквизитами (лучше, чтобы каждый раз при старте сессии, после удалять), при этом первый и последний символы, пароля не хранятся в файле, а добавляются в коде:
from getpass import getpass def get_creds(): if not os.path.exists('pers/.env'): cred = getpass() with open('pers/.env', 'wt') as f_wr: f_wr.write(f'PSWD={cred[1:-1]}') load_dotenv('pers/.env') PSWD = '1'+os.environ['PSWD']+'1' return PSWD return PSWD
Удалим файл, старое значением переменной окружения и вызовем функцию:
!rm pers/.env
del os.environ['PSWD']
USER = 'user' PSWD = get_creds() PSWD
Пароль правильный и он не хранится в файле полностью:
!cat pers/.env
Если вы делаете проект, который будет запускать лицо с другими реквизитами (например, заказчик), удобно функцию get_creds не показывать, а объявить в отдельно модуле, который не попадет в репозиторий. При этом в отдельном общедоступном py файле прописать переменные USER = 'user', PSWD = get_creds(). Во время передачи проекта указать, что следует задать в переменной PSWD пароль для запуска или для большей безопасности прописать там getpass.
keyring
Когда существует опасность доступа злоумышленника к вашим файлам, надежным способом хранения реквизитов является их шифрование. Как вариант, можно воспользоваться модулем keyring. Сначала установим необходимые библиотеки:
pip install keyring keyrings.alt pycryptodome -q
import keyring from keyrings.alt.file import EncryptedKeyring
keyring.set_keyring(EncryptedKeyring())
Для записи или обновления пароля можно использовать функцию set_password модуля keyring. Первый параметр - имя сервиса (ключа), к которому привязан пароль:
keyring.set_password('main', 'user', '1pswd1')
Для получения пароля необходимо указать имя сервиса и логин, а функция при первом ее вызове потребует ввод пароля хранилища, который задавался в set_password:
keyring.get_password('main', 'user')
Для получения пути к файлу с зашифрованным паролем можно вызвать атрибут file_path класса EncryptedKeyring:
EncryptedKeyring().file_path
!cat /root/.local/share/python_keyring/crypted_pass.cfg
Также есть и другие способы получения пути к файлу с реквизитами, которые в зависимости от системы могут сработать или нет: