важный пароль к базе данных зашифровать простой прогой типа XOR заменой простым паролем программы (вас как юзера). При запуске проги запускаете её и она XOR-ит вашим простым паролем пароль базы данных и получаете реально расшифрованный пароль. Надёжность зависит от длины и сложности ваших паролей.
23 сен 2022 в 17:28
Скорее всего пользователь вообще не должен иметь прямого доступа к бд. Если ваше приложение ходит в бд и при этом выполняется в недоверенной среде (у пользователя) — значит, вероятно, вы делаете что-то очень сильно не так
23 сен 2022 в 17:45
24 сен 2022 в 6:29
.conf-файл просто не надо разрешать читать каким попало пользователям. Режим 0600 — и до свидания.
19 окт 2022 в 9:31
19 окт 2022 в 9:34
7 ответов 7
Сортировка: Сброс на вариант по умолчанию
Никакого способа защищенно хранить пароли в программе нет. Пользователю доступны все ее данные, включая пароль и содержимое из базы данных. Максимум, чего вы сможете добиться — обфускации пароля. Для защищенного хранения паролей и т.п. чувствительных данных необходимо использование аппаратного носителя с неизвлекаемыми ключами.
КАК ХРАНИТЬ КЛЮЧИ И ПАРОЛИ | Python 3, Питон 3
Отслеживать
ответ дан 19 окт 2022 в 9:46
user7860670 user7860670
29k 3 3 золотых знака 16 16 серебряных знаков 36 36 бронзовых знаков
Комментарии не предназначены для расширенной дискуссии; разговор перемещён в чат.
20 окт 2022 в 6:27
Если бд на сервере, то сервер должен выполнять с ней работу => все логины и пароли должны храниться на сервере. Программа же должна общаться с сервером посредством запросов, в которых передаются данные, с которыми мы хотим что-то сделать
Отслеживать
ответ дан 21 окт 2022 в 17:11
evgeni2306 evgeni2306
185 8 8 бронзовых знаков
А для авторизации работы с этой программой на сервере (прокси) все равно понадобится локально хранимый пароль. Но это не пароль базы, поэтому с базой в любом случае можно будет делать только то, что реализовано в прокси
23 окт 2022 в 21:32
Есть 2 варианта:
- Вынести пароль и ссылку к бд в dll который при необходимости будет обновляться.
- Создать файл, с определенным методом шифрования и дешифрования (тут есть разные варианты реализации), а ключ к дешифровки хранить непосредственно в .exe файле.
Но лично я бы написал бы простой PHP скрипт на сервере, который бы обращался к базе данных. Если говорить про обычный хостинг, и у пользователя уже хранить в .exe статичную ссылку, а на сервере уже хранить пароль.
Отслеживать
51.5k 195 195 золотых знаков 56 56 серебряных знаков 233 233 бронзовых знака
ответ дан 23 сен 2022 в 15:47
47 6 6 бронзовых знаков
любые строки, которые мы храним в скомпилированных файлах читаются, если этот файл открыть как txt
23 сен 2022 в 15:53
23 сен 2022 в 16:00
пароль поменяется — менять хеш в проге — перекомпиливать, к тому же этот хеш нереально расшифровать же 🙂 Должно быть какое-то хорошее решение, но я его пока не нашел
23 сен 2022 в 16:08
23 сен 2022 в 16:14
«ключ к дешифровки хранить непосредственно в .exe файле» — это эквивалентно хранению пароля базы в .exe c небольшой обфускацией
Шифруем файлы и пароли аки Царь с GPG и Pass!
19 окт 2022 в 9:24
Если нету посредника, который будет соединятся с базой — пароль в том или ином виде не может не быть на клиенте. Клиенту нужно использовать пароль чтоб установить соединение с БД.
Возможно, существуют движки БД или плагины для них, которые позволяют установить соединение с помощью аппаратных ключей или одноразовых токенов, но это довольно редкие варианты, и рассматривать их не буду.
Так же, под «БД» я представляю какую-то СУБД типа MySQL, где очень мало возможностей ограничения доступа.
Возможно, у вас другой движок БД, где сервер представляет всю нужную защиту данных и разграничение доступов, и ваша задача — именно спрятать пароль от соединения в обход клиентской программы.
Соответственно, ответ исходит из этой точки зрения.
Думаю, лучше всего хранить пароль — в зашифрованном виде в конфиге.
На счет шифрования — алгоритм должен быть проверенный временем, то есть например AES. Без велосипедов.
Ключ шифрования — частично захардкодить, частично вычислять в рантайме (например, операции над массивом). Так как компилятор может оптимизировать такой код, следует его написать так, чтоб компилятор не догадался, что результат будет константой. Очень хорошее решение — так же использовать идентификаторы привязанные к железу. Например, «Volume Serial Number» раздела, на котором лежит программа. Тогда даже если скопировать программу на флешку — он не будет работать.
Ну и всю эту красоту прогнать через HMAC.
Еще один мелкий лайфхак обфускации: прогнать base64 через шифр цезаря =)
Еще один интересный способ хранения пароля, который я использовал в одном проекте (в описании я немного упростил схему):
Пароль зашифрован ключем, который есть хешем числа от 1 до 10000. Ни ключ ни это число не сохраняются нигде. При установлении соединения ключ шифрования пароля подбирается в реальном времени. Так же имеется хеш пароля, чтоб убедится что ключ расшифрован правильно.
Отслеживать
ответ дан 19 окт 2022 в 12:18
Давид Манжула Давид Манжула
3,115 10 10 серебряных знаков 23 23 бронзовых знака
Всё это не поможет абсолютно никак, потому что клиент прочитает готовый вычисленный ключ тупо из оперативной памяти
19 окт 2022 в 14:09
20 окт 2022 в 6:17
Ничто не помешает клиенту прочитать пароль ещё перед очисткой памяти
20 окт 2022 в 11:46
21 окт 2022 в 11:24
Мой ответ подразумевает, что речь идёт о локальной системе, т. е. клиентское приложение запускается на том же компьютере, где находится и СУБД, и БД.
Пароль нужно хранить в .conf в зашифрованном виде. Программа читает конфигурацию и дешифрует пароль, используя ключ, жёстко забитый в код программы.
Аргументы: 1) пароль не должен быть зашит в коде, чтобы его можно было менять; 2) пароль не должен быть доступен в открытом виде в конфигурационном файле.
Другого варианта нет. И этот вариант, как и любой другой, не защищён от реверс-инжиниринга.
Если это секретный пароль, то обновлять его в конфигурационном файле нужно с помощью другой программы, в которую забит тот же ключ шифрования.
Тут предлагают всякие варианты с хостингом, серверами и пр. интернетом, но в условии о доступе в сеть речи нет. Это может быть локальная база данных, которую нужно защитить от несанкционированного доступа пользователя. Это сразу отсекает метод защиты через аутентификацию средствами ОС. Защита БД осуществляется приложением, так как только приложение может менять БД и только запрограммированным образом, исключая риск намеренного или ненамеренного повреждения или изменения данных.
Появилась мысль, сам делал такое недавно. Исходя из гипотезы локального применения. Нужно защитить приложение от доступа. Сделать его в виде службы с Web-интерфейсом, приложение запускается от какой-то выделенной учётной записи, доступ к файлам и папкам приложения только у этой учётной записи (ну и система, и администраторы, понятно). Таким образом, нельзя будет изучить исполняемый файл приложения, его бибилиотеки, конфигурационные и другие файлы.
Естественно, всё это подразумевает, что пользователь не обладает правами администратора и не может получить административный доступ к системе.
С уточнёнными условиями неободимо сделать следующее:
- доступ к БД осуществляет серверное backend-ПО;
- клиентское приложение подключается к серверу с помощью учётных данных, которые пользователь вводит интерактивно.
Таким образом, в приложении и его конфигурационных файлах никакие пароли не хранятся.
Источник: ru.stackoverflow.com
Как правильно хранить пароли в базе данных
В этой статье я объясню, как хранить пароли просто и правильно.
Сохранение паролей пользователей в базе данных — обычное дело, но не каждый разработчик делает это правильно. Например, в сегодняшнем code review я обнаружил, что пароли хранятся в виде обычного текста. Когда я спросил разработчика, в чем опасность такого сохранения, он быстро осознал проблему и поинтересовался, было бы решением их зашифровать. Я ответил: «Нет».
В этой статье я объясню, как хранить пароли правильно и просто. Давайте начнем.
Сохранение паролей
Хранить пароль в виде обычного текста — ужасная идея, но хранить его в зашифрованном виде с использованием двустороннего алгоритма также плохо.
Почему? Потому что, если мы зашифруем и сохраним пароль с помощью ключа шифрования и алгоритма, который позволяет нам зашифровать пароль и расшифровать его с помощью этого ключа, любой, у кого есть ключ шифрования, сможет его расшифровать.
Итак, как правильно это сделать?
В большинстве случаев правильным решением является сохранение хеша пароля в базе данных.
Для этого вы должны хешировать пароль, используя различную соль для каждого пользователя, используя односторонний алгоритм, и сохранить результат, удалив исходный пароль. Затем, когда вы хотите проверить пароль, вы снова хешируете пароль из обычного текста, используя тот же алгоритм хеширования и ту же соль, и сравниваете его с хешированным сохраненным значением в базе данных.
Хорошо, но что вы имеете в виду, говоря «используя разные соли для каждого пользователя»?
Соль — это случайные данные, используемые в качестве дополнительных входных данных для одностороннего алгоритма хеширования. Исторически в системе хранилась только криптографическая хеш-функция пароля, но со временем были разработаны дополнительные меры безопасности для защиты от идентифицируемых общих или повторяющихся паролей.
Давайте посмотрим на практику.
Представим, что у нас есть таблица в базе данных для хранения пользователей моего приложения. В этой таблице есть следующие поля, которые мы будем использовать для хранения имени пользователя и пароля:
Следующим шагом является создание уникальной соли для каждого пользователя каждый раз, когда мы создаем пользователя в этой таблице. Для этого я определю класс с методом, который будет генерировать соль. Выполнение этого с использованием любого другого языка программирования аналогично.
- В строке 7 мы определяем длину соли.
- В строке 11 мы создаем экземпляр класса SecureRandom. Этот класс предоставляет криптографически стойкий генератор случайных чисел, предоставляемый JDK (для других языков у нас есть аналогичные библиотеки).
- В строке 16 мы создаем значение соли, а затем возвращаем строку Base64.
Когда у нас есть соль для пользователя, следующим шагом будет хеширование пароля в виде обычного текста с использованием этой соли. Для этого мы собираемся добавить в наш класс метод под названием hashThePlainTextPassword:
- В строке 10 мы указываем итерации и длину PBEKey.
- В строке 13 мы получаем экземпляр SecretKeyFactory.
- В строке 14 мы генерируем секретный ключ.
- В строке 15 мы возвращаем хешированный пароль в строке Base64.
После того, как мы добавили соль к нашему паролю, мы можем сохранить его хеш в таблице пользователя вместе с солью. Обратите внимание, что при использовании одностороннего алгоритма для декодирования пароля мы никогда не узнаем исходное значение пароля в виде обычного текста. Таким образом, даже если вы получите соль пользователя, если вы не знаете исходный пароль в виде открытого текста, вы никогда не сгенерируете тот же хеш.
Итак, как я могу узнать, правильный ли пароль?
Очень просто. Если мы хотим проверить пароль, мы снова хэшируем значение (используя тот же алгоритм хеширования и соль) и сравниваем его с хешированным значением пользователя в базе данных.
Для этого мы собираемся добавить в наш класс метод под названием verifyThePlainTextPassword. Этот метод хеширует открытый текстовый пароль с исходным соленым значением. Теперь, если сохраненное значение в базе данных и сгенерированное хеш-значение идентичны, значит пароль правильный.
Все вместе
Вывод
Как видите, правильно сохранить пароли в базе данных просто, а правильное их хранение позволит избежать многих проблем.
Надеюсь, эта статья оказалась для вас полезной.
Источник: apptractor.ru
Про хранение паролей в БД
Когда встал вопрос хранения паролей, конечно, первой идеей было просто записывать их в открытом виде в соответствующей табличке в базе данных. И все бы ничего, если бы доступ к ней действительно напрямую клиенты получить не могли. Но, к сожалению, в различных веб-приложениях по-прежнему иногда работает такая известная всем SQL-инъекция, не говоря уже о других потенциальных уязвимостях. В вопросах безопасности вообще принято предполагать худшее и готовить план действий и защиту даже на такой случай. Будем считать, что злоумышленник нашел в веб-приложении лазейку, тем или иным способом радостно выгружает себе таблицу с именами и паролями пользователей и дальше уже распоряжается ими, как ему вздумается. В общем случае его дальнейшие действия могут быть следующими:
- выполнение нелегитимных действий от имени пользователей с использованием их учетных данных на уязвимом ресурсе: например, к учетной записи привязана банковская карта, и теперь злоумышленник может ей пользоваться;
- попытка использования полученного пароля на других ресурсах: далеко не всегда пользователи, следуя советам, придумывают каждый раз новые пароли для разных сервисов;
- попытка выявить правило генерации пароля и перейти ко второму пункту: некоторые формируют какое-то правило составления пароля, в итоге на разных ресурсах пароли разные, но подчиняются одному и тому же правилу, которое можно выявить;
- повышение привилегий: в той же таблице может храниться и пароль администратора, со знанием которого иногда можно получить полный контроль над сервером.
Шифрование Хэширование
Идея сразу оказывается не такой хорошей. Что делать? Здорово было бы хранить пароли в зашифрованном виде. Тогда, даже если их извлекут, восстановить не смогут или, по крайней мере, потратят на это слишком много времени. Здесь выбор встает между двумя ветками развития: шифровать пароли или хэшировать.
Разработчики остановились на втором, и, в принципе, понятно, почему. Сравним наших претендентов по разным характеристикам:
- Трудоемкость. Шифрование занимает больше времени, а какое преобразование мы бы ни выбрали, его придется проделывать при каждой проверке пароля. Одним из требований к хэш-функциям же является быстрота выполнения.
- Длина выходных значений. Результат шифрования имеет переменную длину, результат хэширования – всегда одинаковую, а хранить однородные по размеру данные в базе данных очень уж удобно. Не говоря уже о том, что длина пароля в зашифрованном виде будет давать некоторую информацию о длине исходного пароля. Одинаковая длина, правда, приводит к возможности возникновения коллизий, но об этом ниже.
- Управление ключами. Для шифрования требуется ключ, который тоже где-то придется хранить и надеяться, что его никто не найдет. В любом случае, генерация и управление ключами это отдельная история (они не должны быть слабыми, их нужно регулярно менять и так далее).
- Возможность коллизии. При шифровании выходные данные от различных входных даных всегда тоже будут различны. При хэшировании же это не всегда так. Постоянная длина хэша означает ограниченность множества выходных значений хэш-функции, что приводит к возможности коллизии. То есть, допустим, пользователь действительно заморочился и придумал себе по-настоящему классный длинный пароль, в котором есть и спецсимволы, и цифры, и буквы в нижнем и верхнем регистре. Злоумышленник вводит в поле пароля не менее классный пароль “admin”. Сервер для проверки и сравнения хэшей захэшировал его. Хэши совпали. Обидно.
Атаки на хэшированные пароли
Итак, злоумышленник заполучил нашу таблицу с именами пользователей и паролей. Пароли теперь захэшированы, но это нашего атакующего не останавливает, и он всерьез намерен их восстановить. Его возможные действия:
- брутфорс по словарю: если с эталонным паролем администраторов у злоумышленника ничего не вышло, он обратится к словарю популярных паролей и попытает счастья с их хэшами;
- радужные таблицы: вообще сегодня ему, может, не надо будет совсем ничего вычислять и перебирать по словарю. Достаточно будет обратиться к лежащим в сети радужным таблицам. В радужных таблицах содержатся уже вычисленные кем-то до этого хэш-значения и соответствующие им входные данные. Важно отметить, что в силу коллизий, пароль, который предложит радужная таблица, не обязательно будет именно тем, который использует пользователь. Предвычисленные значения есть уже для MD5, SHA1, SHA256, SHA512, а также для их модификаций и некоторых других. Попробовать обратить хэш можно, например, здесь;
- полный перебор: если не поможет и это, придется прибегнуть к брутфорсу и перебирать подряд все возможные пароли, пока вычисленные хэши наконец не совпадут.
MD5 – 627 мс
SHA-1 – 604 мс
SHA-256 – 739 мс
SHA-512 – 1056 мс
А ведь сегодня брутфорс можно распараллелить и выполнить в разы быстрее на GPU (а также на APU, DSP и FPGA). Однако помимо выбора более долгого алгоритма и более длинного выходного результата можно сделать кое-что еще.
Хэширование хэша
Чтобы помешать нарушителю воспользоваться готовыми радужными таблицами, существует техника хэширования пароля несколько раз. То есть вычисляем хэш от хэша от хэша от хэша… и так n раз (надо, правда, сильно с этим не увлекаться, потому что при обычной проверке пароля пользователя серверу тоже придется это проделывать). Теперь так просто по радужной таблице он пароль не найдет, да и время на брутфорс заметно увеличится. Но ничто не остановит злоумышленника от того, чтобы сгенерировать радужную таблицу по словарю паролей, зная алгоритм хэширования. Тем более, для самых популярных комбинаций этого метода такие таблицы уже сгенерированы:
«
Добавить соль по вкусу
Для того, чтобы и это он не смог сделать, пароли сегодня хэшируются с добавлением соли.
Соль – это дополнительная случайная строка, которая приписывается к паролю и хэшируется вместе с ним. Из полученного таким образом хэша по радужной таблице пароль уже не восстановишь. Зная соль и выходной хэш, злоумышленник обречен на брутфорс и никакие заранее вычисленные таблицы ему, скорее всего, не помогут.
Таксономия соления паролей:
1. По принципу соления:
- уникальная соль для каждого пользователя: индивидуальная для каждого пользователя – таким образом, если соль станет известна злоумышленнику, брутить придется пароль каждого по отдельности. И кроме того, даже если два пользователя мыслят одинаково и придумали идентичные пароли, хэши все равно на выходе будут разными;
- глобальная соль: одинакова для всех, используется для всех хэшей;
- и то, и другое.
- в базе: как правило, индивидуальные соли хранятся в той же базе, что и хэши паролей; часто даже в той же строке;
- в коде (читать: в конфиге): глобальную соль обычно хранят не в базе данных, а, например, в конфиге, чтобы нарушителю пришлось потратить время на ее подбор.
- Ему неизвестна глобальная соль, поэтому ее придется брутить.
- Ему известны соли пользователей, но заготовленных таблиц с этими солями у него нет, поэтому пароли придется брутить.
- Процесс этот займет еще больше времени из-за того, что придется хэшировать хэши по 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 повторениями.
Источник: habr.com