Как я могу защитить имя пользователя и пароль MySQL от декомпиляции?

StackOverflow https://stackoverflow.com/questions/442862

Вопрос

Файлы

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-файл настроек и прочитать учетные данные для входа, но это не является угрозой безопасности, поскольку пользователь знал учетные данные для начала.

Второй случай: попытка скрыть учетные данные пользователя от пользователя

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

Другие советы

Вы пишете веб-приложение? Если это так, используйте JNDI для внешней настройки приложения. Обзор доступен здесь :

  

JNDI обеспечивает единый способ   приложение для поиска и доступа к удаленному   услуги по сети. Пульт   Услуга может быть любой услугой предприятия,   в том числе службы обмена сообщениями или   сервис для конкретного приложения, но, из   Конечно, приложение JDBC   интересует в основном база данных   оказание услуг. Когда объект DataSource   создан и зарегистрирован в JNDI   служба именования, приложение может использовать   API JNDI для доступа к этому источнику данных   объект, который затем может быть использован для   подключиться к источнику данных это   представляет.

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

Лучший способ - нигде не хранить пароли. Это достигается использованием хеш-функций для генерации и хранения хешей паролей:

hash("hello") = 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
hash("hbllo") = 58756879c05c68dfac9866712fad6a93f8146f337a69afe7dd238f3364946366
  

Хеш-алгоритмы являются односторонними функциями. Они превращают любое количество данных   в фиксированную длину «отпечатка пальца» это не может быть обращено вспять. Они тоже   обладают свойством, что если входные данные изменятся даже чуть-чуть,   результирующий хеш совершенно другой (см. пример выше). это   отлично подходит для защиты паролей, потому что мы хотим хранить пароли   в форме, которая защищает их, даже если сам файл паролей   скомпрометированы, но в то же время мы должны быть в состоянии проверить, что   пароль пользователя правильный.

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

Теперь возникает вопрос: как лучше хранить пароли? Я бы посоветовал это (решение службы аутентификации и управления пользователями Stormpath's) довольно чертовски идеальный:

<Ол>
  • Ваш пользователь вводит учетные данные, и это проверяется на соответствие хеш пароля
  • Сгенерированы и сохранены хэши паролей, а не пароли
  • Хеши выполняются несколько раз
  • Хеши генерируются с использованием случайно сгенерированной соли
  • Хэши зашифрованы с помощью закрытого ключа
  • Закрытый ключ хранится в физически отличном от хэшей месте
  • Обновлены закрытые ключи в зависимости от времени.
  • Зашифрованные хэши делятся на куски
  • Эти чанки хранятся в физически отдельных местах
  • Очевидно, что вы не Google или банк, так что это решение для вас излишним. Но тогда возникает вопрос: сколько безопасности требует ваш проект, сколько у вас времени и денег?

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

    Например, предположим, что шаг 1 не является приемлемым решением для вашего проекта. Вы не хотите, чтобы пользователи вводили пароль каждый раз, или вам даже не нужно / не нужно, чтобы пользователи знали пароль. Тем не менее, у вас есть конфиденциальная информация, и вы хотите защитить ее. У вас простое приложение, нет сервера для хранения ваших файлов или это слишком хлопотно для вашего проекта. Ваше приложение работает в среде, где невозможно безопасно хранить файлы. Это один из худших случаев, но все же с некоторыми дополнительными мерами безопасности у вас может быть гораздо более безопасное решение. Например, вы можете хранить конфиденциальную информацию в файле и шифровать файл. Вы можете жестко закодировать закрытый ключ шифрования в коде. Вы можете запутать код, так что вам будет немного сложнее его взломать. Для этого существует множество библиотек, см. эту ссылку . (Я хочу еще раз предупредить вас, что это не на 100% безопасно. Умный хакер с необходимыми знаниями и инструментами может взломать это. Но на основе

    Этот вопрос показывает, как хранить пароли и другие данные в зашифрованном файле: 256-битное Java AES-шифрование на основе пароля

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

    Лицензировано под: CC-BY-SA с атрибуция
    Не связан с StackOverflow
    scroll top