Как я могу защитить имя пользователя и пароль MySQL от декомпиляции?
-
22-07-2019 - |
Вопрос
Java .class
можно довольно легко декомпилировать. Как я могу защитить свою базу данных, если мне нужно использовать данные для входа в коде?
Решение
Никогда не вводите пароли в свой код. Это было недавно упомянуто в Топ 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-файл настроек и прочитать учетные данные для входа, но это не является угрозой безопасности, поскольку пользователь знал учетные данные для начала.
Второй случай: попытка скрыть учетные данные пользователя от пользователя
Это более сложный случай: пользователь не должен знать учетные данные для входа, но все еще нуждается в доступе к базе данных. В этом случае пользователь, запускающий приложение, имеет прямой доступ к базе данных, а это значит, что программе необходимо заранее знать учетные данные для входа. Решение, которое я упомянул выше, не подходит для этого случая. Вы можете сохранить учетные данные для входа в базу данных в файле настроек, но пользователь сможет прочитать этот файл, так как
Другие советы
Поместите пароль в файл, который будет читать приложение. НИКОГДА не вставляйте пароли в исходный файл. Период.
В Ruby есть такой малоизвестный модуль, который называется DBI :: DBRC . Я не сомневаюсь, что у Java есть эквивалент. Во всяком случае, это не сложно написать один.
Вы пишете веб-приложение? Если это так, используйте JNDI для внешней настройки приложения. Обзор доступен здесь : р>
JNDI обеспечивает единый способ приложение для поиска и доступа к удаленному услуги по сети. Пульт Услуга может быть любой услугой предприятия, в том числе службы обмена сообщениями или сервис для конкретного приложения, но, из Конечно, приложение JDBC интересует в основном база данных оказание услуг. Когда объект DataSource создан и зарегистрирован в JNDI служба именования, приложение может использовать API JNDI для доступа к этому источнику данных объект, который затем может быть использован для подключиться к источнику данных это представляет. р>
Независимо от того, что вы делаете, конфиденциальная информация будет где-то храниться в каком-то файле. Ваша цель состоит в том, чтобы сделать его настолько сложным, насколько это возможно. Сколько из этого вы можете достичь, зависит от вашего проекта, потребностей и толщины кошелька вашей компании. Р>
Лучший способ - нигде не хранить пароли. Это достигается использованием хеш-функций для генерации и хранения хешей паролей:
hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366
Хеш-алгоритмы являются односторонними функциями. Они превращают любое количество данных в фиксированную длину «отпечатка пальца» это не может быть обращено вспять. Они тоже обладают свойством, что если входные данные изменятся даже чуть-чуть, результирующий хеш совершенно другой (см. пример выше). это отлично подходит для защиты паролей, потому что мы хотим хранить пароли в форме, которая защищает их, даже если сам файл паролей скомпрометированы, но в то же время мы должны быть в состоянии проверить, что пароль пользователя правильный.
Не связанная с этим заметка: В старые времена Интернета, когда вы нажимали ссылку «забыл мой пароль», веб-сайты отправляли вам по электронной почте ваш пароль в виде простого текста. Вероятно, они где-то хранили их в базе данных. Когда хакеры получают доступ к своей базе данных, они получают доступ ко всем паролям. Поскольку многие пользователи использовали один и тот же пароль на нескольких веб-сайтах, это было огромной проблемой безопасности. К счастью, в настоящее время это не обычная практика.
Теперь возникает вопрос: как лучше хранить пароли? Я бы посоветовал это (решение службы аутентификации и управления пользователями Stormpath's) довольно чертовски идеальный:
<Ол>Очевидно, что вы не Google или банк, так что это решение для вас излишним. Но тогда возникает вопрос: сколько безопасности требует ваш проект, сколько у вас времени и денег? Р>
Для многих приложений, хотя это и не рекомендуется, хранение жестко запрограммированного пароля в коде может быть достаточно хорошим решением. Однако, легко добавив пару дополнительных шагов безопасности из приведенного выше списка, вы можете сделать свое приложение намного более безопасным.
Например, предположим, что шаг 1 не является приемлемым решением для вашего проекта. Вы не хотите, чтобы пользователи вводили пароль каждый раз, или вам даже не нужно / не нужно, чтобы пользователи знали пароль. Тем не менее, у вас есть конфиденциальная информация, и вы хотите защитить ее. У вас простое приложение, нет сервера для хранения ваших файлов или это слишком хлопотно для вашего проекта. Ваше приложение работает в среде, где невозможно безопасно хранить файлы. Это один из худших случаев, но все же с некоторыми дополнительными мерами безопасности у вас может быть гораздо более безопасное решение. Например, вы можете хранить конфиденциальную информацию в файле и шифровать файл. Вы можете жестко закодировать закрытый ключ шифрования в коде. Вы можете запутать код, так что вам будет немного сложнее его взломать. Для этого существует множество библиотек, см. эту ссылку . (Я хочу еще раз предупредить вас, что это не на 100% безопасно. Умный хакер с необходимыми знаниями и инструментами может взломать это. Но на основе
Этот вопрос показывает, как хранить пароли и другие данные в зашифрованном файле: 256-битное Java AES-шифрование на основе пароля
MD5 - это алгоритм хеширования, а не алгоритм шифрования, короче говоря, вы не можете получить обратно хэшированную информацию, вы можете только сравнить. В идеале его следует использовать при хранении информации об аутентификации пользователя, а не имени пользователя и пароля. имя пользователя db и pwd должны быть зашифрованы и сохранены в файле конфигурации, чтобы сделать это меньше всего.