Перейти к содержимому

Как хранить пароли в базе данных

  • автор:

zmts / passwords.md

Суть не в дешифровке хеша из базы и сверке его с введенным паролем, а в создании нового хеша из нового введенного юзером пароля и соли из базы и последующей сверкой нового хеша с хешем из БД.

Практическое применение: создание хеша

var bcrypt = require('bcryptjs'); bcrypt.genSalt(10, function(error, salt) < // генерим соль >> передаем ее в колбек bcrypt.hash("some_password_from_input", salt, function(error, hash) < // берем пароль из инпута + соль и генерим хеш // получаем хеш и сохраняем в БД // в случае использования bcryptjs необходимость хранения соли отпадает, почему объясняется ниже >); >); 

Практическое применение: проверка хешей

  1. Берем пароль из инпута, хеш из БД(hash_from_db)
  2. Ф-ция compare сама извлекает соль из хеша(hash_from_db) и солит им нововведенный пароль
  3. И сверивает новый хеш с хешем из БД(hash_from_db) Вот почему мы не сохраняли соль в БД, bcryptjs сам знает как извлечь соль из хеша, и унас отпадает необходимость хранить соль отдельно
bcrypt.compare("some_password", hash_from_db, function(error, result) < if (result)< // авторизируем юзера >>); 

Откуда bcrypt.compare берет соль

var sol = bcrypt.genSaltSync(); >> '$2a$10$ydKFuX0Jfxsega193bReze' var myHash = bcrypt.hashSync('123456', sol); >> '$2a$10$ydKFuX0Jfxsega193bRezezqVklYDdrYSAHk5ho1uE8CPDuqNA8p6' 

Первые 29 символов и есть соль $2a$10$ydKFuX0Jfxsega193bReze

  • https://habrahabr.ru/post/210760/
  • https://habrahabr.ru/post/130965/
  • https://www.youtube.com/watch?v=rCIsuMEFRro

4 способа безопасно хранить пароли

Запоминать или записывать пароли на листочек — так себе затея. Рано или поздно вы забудете какой-то не самый часто используемый пароль или потеряете список. Очевидно, что без продуманной и безопасной системы хранения не обойтись. В этой статье мы расскажем про 4 способа хранения паролей без ручки и листочка.

Фото: Pixabay

Зашифрованный файл

Записывать пароли в текстовый файл, по сути, сродни тому же листочку бумаги. Однако здесь есть и некоторые преимущества. Во-первых, вам не нужно вводить пароль вручную — достаточно его просто скопировать. Во-вторых, файл можно дополнительно защитить от несанкционированного доступа (хотя при желании на Aliexpress можно купить и блокнот с кодовым замком). В-третьих, его можно залить на облако и всегда иметь при себе.

Нажми, чтобы узнать больше

Если и прибегать к этому способу, то файл с данными нужно обязательно шифровать. Сделать это можно разными способами, например, зашифровать заметку в приложениях вроде Evernote. Также можно упаковать файл в запароленный архив или разместить его на зашифрованную область жесткого диска или даже внешний накопитель.

В таком случае вам нужно знать только один пароль — для доступа к файлу. Но надежность этого метода ограничена надежностью сервиса или оборудования, на котором хранится файл, а также сложностью пароля для доступа к нему. Кроме того, этот способ едва ли подойдет для хранения большого количества записей. Структурировать текстовую информацию может быть не так просто. Если в вашем владении сотни аккаунтов, нужно более продвинутое решение.

Менеджер паролей

Гораздо более удобный способ — использовать менеджер паролей. Это специализированная программа, которая позволяет генерировать и хранить пароли. Пользователю нужно только запомнить мастер-пароль для доступа к базе данных.

Возможности у разных программ могут отличаться. Например, KeePass в базовом варианте — довольно скромная по возможностям программа. В целях безопасности программа даже не выполняет автоматическое обновление. Все новые версии нужно устанавливать вручную, скачивая с официального сайта. Однако расширить функционал можно при помощи многочисленных плагинов. Среди прочих можно найти расширения для синхронизации, импорта и экспорта базы данных, автоматического создания резервных копий.

Интерфейс KeePass предельно аскетичный

Есть и более дружелюбные к неопытным пользователям приложения от именитых разработчиков. Например, Kaspersky Password Manager из коробки умеет автоматически синхронизировать пароли между устройствами. Однако у бесплатной версии есть ограничение на 15 записей.

Разумеется, приложений для менеджмента паролей намного больше. Но доверять пароли первому попавшемуся сервису и приложению нельзя. Используйте только те сервисы, которые уже заработали доверие у пользователей или имеют открытый исходный код и многократно проверены сообществом. К популярным решениям можно отнести сервисы 1password и Lastpass. Впрочем, слепо доверять даже надежным программам рискованно. К примеру, в 2015 году Lastpass был взломан, о чем свидетельствует запись в официальном блоге компании. Поэтому прежде чем доверять свои данные тому или иному сервису, поищите информацию о взломах и сливах в сети.

Браузер

Хранить пароли можно и в браузере. Такая функция есть в Chrome, Firefox и других популярных браузерах. Причем нельзя сказать, что это совсем небезопасно. Так, можно настроить мастер-пароль для доступа к базе, а аккаунт защитить двухфакторной авторизацией. Для большей надежности, например защиты от окружающих людей или коллег, можно поставить пароль даже на сам браузер. Впрочем, безопасность на 100% гарантировать никто не может. При использовании определенных уязвимостей, злоумышленник вполне может получить доступ к паролям. К примеру, научное исследование по уязвимости Spectre наглядно демонстрирует кражу пароля из Google Chrome, а также расширения LastPass.

Кроме того, встроенный менеджер паролей предлагает куда меньший функционал. В «Диспетчере паролей» Chrome вы не сможете добавить сторонний пароль для входа в программу или приложение. Также вы не сможете записать другую конфиденциальную информацию — кодовое слово, лицензионный ключ или даже фотографию водительского удостоверения. Более того, если ваши пароли сохранены в одном браузере, то, пересев на другой, вы уже не получите к ним доступ.

Аппаратное решение

Если одной программы для хранения паролей вам недостаточно, можно приобрести аппаратное решение. По сути, это устройство размером и видом напоминающее обычную флешку. Хранящиеся на нем данные зашифрованы, а доступ можно получить только при знании пин-кода. Пользоваться устройством просто — достаточно подключить его к компьютеру, планшету или другому девайсу и выбрать нужную запись в базе. Проще говоря, это такая виртуальная клавиатура, которая будет вводить нужный пароль вместо вас. Это довольно удобное решение, чтобы всегда иметь при себе базу данных с паролями, которую не страшно потерять.

Что еще следует знать

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

Проверьте, не утекли ли ваши пароли в сеть. Не лишним будет периодически проверять пароли на утечки. Сделать это можно при помощи сайтов вроде haveibeenpwned.com. Подробнее можно прочитать в нашем материале «Как узнать, не утекли ли ваши пароли в сеть».

Это тоже интересно:

  • Проверьте, за какое время смогут подобрать ваш пароль
  • Как узнать, не утекли ли ваши пароли в сеть

Где лучше(безопаснее) всего в программе хранить пароль от БД?

важный пароль к базе данных зашифровать простой прогой типа XOR заменой простым паролем программы (вас как юзера). При запуске проги запускаете её и она XOR-ит вашим простым паролем пароль базы данных и получаете реально расшифрованный пароль. Надёжность зависит от длины и сложности ваших паролей.

23 сен 2022 в 17:28

Скорее всего пользователь вообще не должен иметь прямого доступа к бд. Если ваше приложение ходит в бд и при этом выполняется в недоверенной среде (у пользователя) — значит, вероятно, вы делаете что-то очень сильно не так

23 сен 2022 в 17:45

@andreymal я не совсем понял ваш ответ, вы бы не могли разъяснить подробнее, что я делаю не так? И вероятно, вы можете посоветовать литературу, где я могу об этом почитать/научиться этому?

24 сен 2022 в 6:29
.conf-файл просто не надо разрешать читать каким попало пользователям. Режим 0600 — и до свидания.
19 окт 2022 в 9:31

@user_587 Вы видимо не в курсе, как работают подобные файловые разрешения. «режим 0600» фактически устанавливает только номинальные ограничения

19 окт 2022 в 9:34

7 ответов 7

Сортировка: Сброс на вариант по умолчанию

Никакого способа защищенно хранить пароли в программе нет. Пользователю доступны все ее данные, включая пароль и содержимое из базы данных. Максимум, чего вы сможете добиться — обфускации пароля. Для защищенного хранения паролей и т.п. чувствительных данных необходимо использование аппаратного носителя с неизвлекаемыми ключами.

Отслеживать
ответ дан 19 окт 2022 в 9:46
user7860670 user7860670
29.7k 3 3 золотых знака 17 17 серебряных знаков 36 36 бронзовых знаков
Комментарии не предназначены для расширенной дискуссии; разговор перемещён в чат.
20 окт 2022 в 6:27

Если бд на сервере, то сервер должен выполнять с ней работу => все логины и пароли должны храниться на сервере. Программа же должна общаться с сервером посредством запросов, в которых передаются данные, с которыми мы хотим что-то сделать

Отслеживать
ответ дан 21 окт 2022 в 17:11
evgeni2306 evgeni2306
175 8 8 бронзовых знаков

А для авторизации работы с этой программой на сервере (прокси) все равно понадобится локально хранимый пароль. Но это не пароль базы, поэтому с базой в любом случае можно будет делать только то, что реализовано в прокси

23 окт 2022 в 21:32

Есть 2 варианта:

  1. Вынести пароль и ссылку к бд в dll который при необходимости будет обновляться.
  2. Создать файл, с определенным методом шифрования и дешифрования (тут есть разные варианты реализации), а ключ к дешифровки хранить непосредственно в .exe файле.

Но лично я бы написал бы простой PHP скрипт на сервере, который бы обращался к базе данных. Если говорить про обычный хостинг, и у пользователя уже хранить в .exe статичную ссылку, а на сервере уже хранить пароль.

Отслеживать
51.6k 201 201 золотой знак 65 65 серебряных знаков 246 246 бронзовых знаков
ответ дан 23 сен 2022 в 15:47
47 6 6 бронзовых знаков
любые строки, которые мы храним в скомпилированных файлах читаются, если этот файл открыть как txt
23 сен 2022 в 15:53

@SpaceResearcher тогда шифровать строку в с++ и сохраняй ее хэш, а после запуска программы, считывай хэш из файла и декодируй

23 сен 2022 в 16:00

пароль поменяется — менять хеш в проге — перекомпиливать, к тому же этот хеш нереально расшифровать же 🙂 Должно быть какое-то хорошее решение, но я его пока не нашел

23 сен 2022 в 16:08

@SpaceResearcher сделай тогда по третьему варианту Но лично я бы написал бы простой php скрипт на сервере, который бы обращался к базе данной, если говорить про обычный хостинг, и у пользователя уже хранить в .exe статичную ссылку, а на сервере уже хранить пароль.

23 сен 2022 в 16:14

«ключ к дешифровки хранить непосредственно в .exe файле» — это эквивалентно хранению пароля базы в .exe c небольшой обфускацией

19 окт 2022 в 9:24

Если нету посредника, который будет соединятся с базой — пароль в том или ином виде не может не быть на клиенте. Клиенту нужно использовать пароль чтоб установить соединение с БД.

Возможно, существуют движки БД или плагины для них, которые позволяют установить соединение с помощью аппаратных ключей или одноразовых токенов, но это довольно редкие варианты, и рассматривать их не буду.

Так же, под «БД» я представляю какую-то СУБД типа MySQL, где очень мало возможностей ограничения доступа.
Возможно, у вас другой движок БД, где сервер представляет всю нужную защиту данных и разграничение доступов, и ваша задача — именно спрятать пароль от соединения в обход клиентской программы.

Соответственно, ответ исходит из этой точки зрения.

Думаю, лучше всего хранить пароль — в зашифрованном виде в конфиге.

На счет шифрования — алгоритм должен быть проверенный временем, то есть например AES. Без велосипедов.

Ключ шифрования — частично захардкодить, частично вычислять в рантайме (например, операции над массивом). Так как компилятор может оптимизировать такой код, следует его написать так, чтоб компилятор не догадался, что результат будет константой. Очень хорошее решение — так же использовать идентификаторы привязанные к железу. Например, «Volume Serial Number» раздела, на котором лежит программа. Тогда даже если скопировать программу на флешку — он не будет работать.

Ну и всю эту красоту прогнать через HMAC.

Еще один мелкий лайфхак обфускации: прогнать base64 через шифр цезаря =)

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

Отслеживать
ответ дан 19 окт 2022 в 12:18
Давид Манжула Давид Манжула
3,125 11 11 серебряных знаков 23 23 бронзовых знака

Всё это не поможет абсолютно никак, потому что клиент прочитает готовый вычисленный ключ тупо из оперативной памяти

19 окт 2022 в 14:09

@andreymal разве? Пароль обычно используется только для соединения с базой. После того как соединение установлено и пароль больше не нужен — можно очистить память и освободить переменную

20 окт 2022 в 6:17
Ничто не помешает клиенту прочитать пароль ещё перед очисткой памяти
20 окт 2022 в 11:46

@andreymal это мгновение между расшифровкой пароля, отправкой и очисткой памяти? Ну можно еще насыпать мусора в памяти, чтоб было сложнее найти

21 окт 2022 в 11:24

Мой ответ подразумевает, что речь идёт о локальной системе, т. е. клиентское приложение запускается на том же компьютере, где находится и СУБД, и БД.

Пароль нужно хранить в .conf в зашифрованном виде. Программа читает конфигурацию и дешифрует пароль, используя ключ, жёстко забитый в код программы.

Аргументы: 1) пароль не должен быть зашит в коде, чтобы его можно было менять; 2) пароль не должен быть доступен в открытом виде в конфигурационном файле.

Другого варианта нет. И этот вариант, как и любой другой, не защищён от реверс-инжиниринга.

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

Тут предлагают всякие варианты с хостингом, серверами и пр. интернетом, но в условии о доступе в сеть речи нет. Это может быть локальная база данных, которую нужно защитить от несанкционированного доступа пользователя. Это сразу отсекает метод защиты через аутентификацию средствами ОС. Защита БД осуществляется приложением, так как только приложение может менять БД и только запрограммированным образом, исключая риск намеренного или ненамеренного повреждения или изменения данных.

Появилась мысль, сам делал такое недавно. Исходя из гипотезы локального применения. Нужно защитить приложение от доступа. Сделать его в виде службы с Web-интерфейсом, приложение запускается от какой-то выделенной учётной записи, доступ к файлам и папкам приложения только у этой учётной записи (ну и система, и администраторы, понятно). Таким образом, нельзя будет изучить исполняемый файл приложения, его бибилиотеки, конфигурационные и другие файлы.

Естественно, всё это подразумевает, что пользователь не обладает правами администратора и не может получить административный доступ к системе.

С уточнёнными условиями неободимо сделать следующее:

  1. доступ к БД осуществляет серверное backend-ПО;
  2. клиентское приложение подключается к серверу с помощью учётных данных, которые пользователь вводит интерактивно.

Таким образом, в приложении и его конфигурационных файлах никакие пароли не хранятся.

Про хранение паролей в БД

Когда встал вопрос хранения паролей, конечно, первой идеей было просто записывать их в открытом виде в соответствующей табличке в базе данных. И все бы ничего, если бы доступ к ней действительно напрямую клиенты получить не могли. Но, к сожалению, в различных веб-приложениях по-прежнему иногда работает такая известная всем SQL-инъекция, не говоря уже о других потенциальных уязвимостях. В вопросах безопасности вообще принято предполагать худшее и готовить план действий и защиту даже на такой случай. Будем считать, что злоумышленник нашел в веб-приложении лазейку, тем или иным способом радостно выгружает себе таблицу с именами и паролями пользователей и дальше уже распоряжается ими, как ему вздумается. В общем случае его дальнейшие действия могут быть следующими:

  • выполнение нелегитимных действий от имени пользователей с использованием их учетных данных на уязвимом ресурсе: например, к учетной записи привязана банковская карта, и теперь злоумышленник может ей пользоваться;
  • попытка использования полученного пароля на других ресурсах: далеко не всегда пользователи, следуя советам, придумывают каждый раз новые пароли для разных сервисов;
  • попытка выявить правило генерации пароля и перейти ко второму пункту: некоторые формируют какое-то правило составления пароля, в итоге на разных ресурсах пароли разные, но подчиняются одному и тому же правилу, которое можно выявить;
  • повышение привилегий: в той же таблице может храниться и пароль администратора, со знанием которого иногда можно получить полный контроль над сервером.

Шифрование Хэширование

Идея сразу оказывается не такой хорошей. Что делать? Здорово было бы хранить пароли в зашифрованном виде. Тогда, даже если их извлекут, восстановить не смогут или, по крайней мере, потратят на это слишком много времени. Здесь выбор встает между двумя ветками развития: шифровать пароли или хэшировать. Разработчики остановились на втором, и, в принципе, понятно, почему. Сравним наших претендентов по разным характеристикам:

  1. Трудоемкость. Шифрование занимает больше времени, а какое преобразование мы бы ни выбрали, его придется проделывать при каждой проверке пароля. Одним из требований к хэш-функциям же является быстрота выполнения.
  2. Длина выходных значений. Результат шифрования имеет переменную длину, результат хэширования – всегда одинаковую, а хранить однородные по размеру данные в базе данных очень уж удобно. Не говоря уже о том, что длина пароля в зашифрованном виде будет давать некоторую информацию о длине исходного пароля. Одинаковая длина, правда, приводит к возможности возникновения коллизий, но об этом ниже.
  3. Управление ключами. Для шифрования требуется ключ, который тоже где-то придется хранить и надеяться, что его никто не найдет. В любом случае, генерация и управление ключами это отдельная история (они не должны быть слабыми, их нужно регулярно менять и так далее).
  4. Возможность коллизии. При шифровании выходные данные от различных входных даных всегда тоже будут различны. При хэшировании же это не всегда так. Постоянная длина хэша означает ограниченность множества выходных значений хэш-функции, что приводит к возможности коллизии. То есть, допустим, пользователь действительно заморочился и придумал себе по-настоящему классный длинный пароль, в котором есть и спецсимволы, и цифры, и буквы в нижнем и верхнем регистре. Злоумышленник вводит в поле пароля не менее классный пароль “admin”. Сервер для проверки и сравнения хэшей захэшировал его. Хэши совпали. Обидно.

Атаки на хэшированные пароли

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

  • брутфорс по словарю: если с эталонным паролем администраторов у злоумышленника ничего не вышло, он обратится к словарю популярных паролей и попытает счастья с их хэшами;
  • радужные таблицы: вообще сегодня ему, может, не надо будет совсем ничего вычислять и перебирать по словарю. Достаточно будет обратиться к лежащим в сети радужным таблицам. В радужных таблицах содержатся уже вычисленные кем-то до этого хэш-значения и соответствующие им входные данные. Важно отметить, что в силу коллизий, пароль, который предложит радужная таблица, не обязательно будет именно тем, который использует пользователь. Предвычисленные значения есть уже для MD5, SHA1, SHA256, SHA512, а также для их модификаций и некоторых других. Попробовать обратить хэш можно, например, здесь;
  • полный перебор: если не поможет и это, придется прибегнуть к брутфорсу и перебирать подряд все возможные пароли, пока вычисленные хэши наконец не совпадут.

MD5 – 627 мс
SHA-1 – 604 мс
SHA-256 – 739 мс
SHA-512 – 1056 мс

А ведь сегодня брутфорс можно распараллелить и выполнить в разы быстрее на GPU (а также на APU, DSP и FPGA). Однако помимо выбора более долгого алгоритма и более длинного выходного результата можно сделать кое-что еще.

Хэширование хэша

Чтобы помешать нарушителю воспользоваться готовыми радужными таблицами, существует техника хэширования пароля несколько раз. То есть вычисляем хэш от хэша от хэша от хэша… и так n раз (надо, правда, сильно с этим не увлекаться, потому что при обычной проверке пароля пользователя серверу тоже придется это проделывать). Теперь так просто по радужной таблице он пароль не найдет, да и время на брутфорс заметно увеличится. Но ничто не остановит злоумышленника от того, чтобы сгенерировать радужную таблицу по словарю паролей, зная алгоритм хэширования. Тем более, для самых популярных комбинаций этого метода такие таблицы уже сгенерированы:

«

Добавить соль по вкусу

Для того, чтобы и это он не смог сделать, пароли сегодня хэшируются с добавлением соли.
Соль – это дополнительная случайная строка, которая приписывается к паролю и хэшируется вместе с ним. Из полученного таким образом хэша по радужной таблице пароль уже не восстановишь. Зная соль и выходной хэш, злоумышленник обречен на брутфорс и никакие заранее вычисленные таблицы ему, скорее всего, не помогут.
Таксономия соления паролей:

1. По принципу соления:

  • уникальная соль для каждого пользователя: индивидуальная для каждого пользователя – таким образом, если соль станет известна злоумышленнику, брутить придется пароль каждого по отдельности. И кроме того, даже если два пользователя мыслят одинаково и придумали идентичные пароли, хэши все равно на выходе будут разными;
  • глобальная соль: одинакова для всех, используется для всех хэшей;
  • и то, и другое.
  • в базе: как правило, индивидуальные соли хранятся в той же базе, что и хэши паролей; часто даже в той же строке;
  • в коде (читать: в конфиге): глобальную соль обычно хранят не в базе данных, а, например, в конфиге, чтобы нарушителю пришлось потратить время на ее подбор.
  1. Ему неизвестна глобальная соль, поэтому ее придется брутить.
  2. Ему известны соли пользователей, но заготовленных таблиц с этими солями у него нет, поэтому пароли придется брутить.
  3. Процесс этот займет еще больше времени из-за того, что придется хэшировать хэши по n раз.

Как хранят пароли различные CMS

WordPress

До версий 3.х пароли просто хэшировались с помощью MD5. Сейчас используется библиотека phpass. По умолчанию к паролю спереди приписывается соль и полученная строка хэшируется MD5 2^8 раз.

Joomla

До версии 1.0.12 использовался просто MD5. Используется библиотека phpass, по умолчанию bcrypt с солью и 2^10 повторениями.

Drupal

До версии 6 md5 без соли. Используется библиотека phpass. По умолчанию соленый sha512 с 2^16 повторениями.

Silverstripe

Использует соленый Blowfish c 2^10 повторениями.

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

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