.class
Файлы Java довольно легко декомпилировать. Как я могу защитить свою базу данных, если мне нужно использовать данные для входа в код?
java
mysql
security
reverse-engineering
decompiling
Якоб Косороба
источник
источник
Ответы:
Никогда не вставляйте пароли в свой код жестко. Это недавно было внесено в список 25 самых опасных ошибок программирования :
Вы должны хранить информацию о конфигурации, включая пароли, в отдельном файле, который приложение читает при запуске. Это единственный реальный способ предотвратить утечку пароля в результате декомпиляции (никогда не компилируйте его в двоичный файл для начала).
Подробнее об этой распространенной ошибке вы можете прочитать в статье CWE-259 . В статье содержится более подробное определение, примеры и много другой информации о проблеме.
В Java один из самых простых способов сделать это - использовать класс Preferences. Он предназначен для хранения всевозможных настроек программы, некоторые из которых могут включать имя пользователя и пароль.
import java.util.prefs.Preferences; public class DemoApplication { Preferences preferences = Preferences.userNodeForPackage(DemoApplication.class); public void setCredentials(String username, String password) { preferences.put("db_username", username); preferences.put("db_password", password); } public String getUsername() { return preferences.get("db_username", null); } public String getPassword() { return preferences.get("db_password", null); } // your code here }
В приведенном выше коде вы можете вызвать
setCredentials
метод после отображения диалогового окна с запросом имени пользователя и пароля. Если вам необходимо подключиться к базе данных, вы можете просто использоватьgetUsername
иgetPassword
методы для получения сохраненных значений. Учетные данные для входа в систему не будут жестко закодированы в ваших двоичных файлах, поэтому декомпиляция не представляет угрозы безопасности.Важное примечание: файлы настроек - это просто текстовые XML-файлы. Убедитесь, что вы предприняли соответствующие шаги для предотвращения просмотра неавторизованных пользователей неавторизованных файлов (разрешения UNIX, разрешения Windows и т. Д.). В Linux, по крайней мере, это не проблема, потому что при вызове создается
Preferences.userNodeForPackage
XML-файл в домашнем каталоге текущего пользователя, который в любом случае не читается другими пользователями. В Windows ситуация может быть иной.Более важные примечания: в комментариях к этому и другим ответам было много обсуждений о том, какая архитектура является правильной для этой ситуации. В исходном вопросе на самом деле не упоминается контекст, в котором используется приложение, поэтому я расскажу о двух ситуациях, которые могу придумать. Первый - это случай, когда человек, использующий программу, уже знает (и имеет право знать) учетные данные базы данных. Во втором случае вы, разработчик, пытаетесь сохранить в секрете учетные данные базы данных от лица, использующего программу.
Первый случай: пользователю разрешено знать учетные данные для входа в базу данных
В этом случае сработает решение, о котором я говорил выше. Класс Java
Preference
будет хранить имя пользователя и пароль в виде обычного текста, но файл настроек будет доступен для чтения только авторизованному пользователю. Пользователь может просто открыть XML-файл настроек и прочитать учетные данные для входа в систему, но это не представляет угрозы для безопасности, поскольку пользователь изначально знал учетные данные.Второй случай: попытка скрыть учетные данные для входа от пользователя
Это более сложный случай: пользователь не должен знать учетные данные для входа, но ему по-прежнему нужен доступ к базе данных. В этом случае пользователь, запускающий приложение, имеет прямой доступ к базе данных, что означает, что программе необходимо заранее знать учетные данные для входа. Упомянутое выше решение не подходит для этого случая. Вы можете сохранить учетные данные для входа в базу данных в файле настроек, но пользователь сможет читать этот файл, поскольку он будет владельцем. На самом деле, на самом деле нет хорошего способа безопасного использования этого кейса.
Правильный случай: использование многоуровневой архитектуры
Правильный способ сделать это - создать промежуточный уровень между сервером базы данных и клиентским приложением, который аутентифицирует отдельных пользователей и позволяет выполнять ограниченный набор операций. У каждого пользователя будут свои собственные учетные данные для входа, но не для сервера базы данных. Учетные данные позволят получить доступ к среднему уровню (уровню бизнес-логики) и будут разными для каждого пользователя.
У каждого пользователя будет собственное имя пользователя и пароль, которые можно будет хранить локально в файле настроек без какого-либо риска для безопасности. Это называется трехуровневой архитектурой (уровни - это ваш сервер базы данных, сервер бизнес-логики и клиентское приложение). Это более сложный, но на самом деле наиболее безопасный способ делать подобные вещи.
Основной порядок действий:
getInventoryList
.Обратите внимание, что в течение всего процесса клиентское приложение никогда не подключается напрямую к базе данных . Уровень бизнес-логики получает запрос от аутентифицированного пользователя, обрабатывает запрос клиента на список инвентаризации и только после этого выполняет SQL-запрос.
источник
Поместите пароль в файл, который будет читать приложение. НИКОГДА не вставляйте пароли в исходный файл. Период.
В Ruby для такого использования есть малоизвестный модуль DBI :: DBRC . Не сомневаюсь, что у Java есть аналог. Во всяком случае, написать его несложно.
источник
Вы пишете веб-приложение? Если это так, используйте JNDI для внешней настройки приложения. Обзор доступен здесь :
источник
Независимо от того, что вы делаете, конфиденциальная информация будет где-то храниться в каком-то файле. Ваша цель - сделать это как можно сложнее. Насколько это удастся, зависит от вашего проекта, потребностей и толщины кошелька вашей компании.
Лучший способ - нигде не хранить пароли. Это достигается за счет использования хэш-функций для генерации и хранения хэшей паролей:
hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366
Несвязанное примечание: в старые времена Интернета, когда вы нажимали ссылку «забыл мой пароль», веб-сайты отправляли вам по электронной почте ваш пароль в виде обычного текста. Вероятно, они хранили их где-то в базе данных. Когда хакеры получали доступ к своей базе данных, они получали доступ ко всем паролям. Поскольку многие пользователи использовали один и тот же пароль на нескольких веб-сайтах, это было огромной проблемой безопасности. К счастью, в настоящее время это не обычная практика.
Теперь возникает вопрос: как лучше всего хранить пароли? Я бы счел это решение ( Stormpath службы аутентификации и управления пользователями) чертовски идеальным:
Очевидно, что вы не гугл или банк, так что это избыточное решение для вас. Но тогда возникает вопрос: какой уровень безопасности требует ваш проект, сколько у вас времени и денег?
Для многих приложений, хотя это и не рекомендуется, хранение жестко закодированного пароля в коде может быть достаточно хорошим решением. Однако, легко добавив пару дополнительных шагов безопасности из приведенного выше списка, вы можете сделать свое приложение намного более безопасным.
Например, предположим, что шаг 1 не является приемлемым решением для вашего проекта. Вы не хотите, чтобы пользователи вводили пароль каждый раз, или вы даже не хотите, чтобы пользователи знали пароль. Тем не менее, у вас где-то есть конфиденциальная информация, и вы хотите ее защитить. У вас есть простое приложение, нет сервера для хранения ваших файлов, или это слишком хлопотно для вашего проекта. Ваше приложение работает в средах, в которых невозможно безопасно хранить файлы. Это один из худших случаев, но все же с некоторыми дополнительными мерами безопасности вы можете получить гораздо более безопасное решение. Например, вы можете сохранить конфиденциальную информацию в файле и зашифровать его. Вы можете жестко запрограммировать закрытый ключ шифрования в коде. Вы можете обфускировать код, чтобы кому-то было труднее его взломать.по этой ссылке . (Я хочу еще раз предупредить вас, что это не на 100% безопасно. Умный хакер с правильными знаниями и инструментами может это взломать. Но, исходя из ваших требований и потребностей, это может быть достаточно хорошим решением для вас).
источник
Этот вопрос показывает, как хранить пароли и другие данные в зашифрованном файле: 256-битное шифрование на основе паролей AES Java
источник
MD5 - это алгоритм хеширования, а не алгоритм шифрования, короче говоря, вы не можете вернуться к хешированию, вы можете только сравнивать. В идеале его следует использовать при хранении информации для аутентификации пользователя, а не имени пользователя и пароля db. Имя пользователя db и pwd должны быть зашифрованы и сохранены в файле конфигурации, по крайней мере.
источник