Хранение паролей в обратимой форме - PullRequest
16 голосов
/ 04 ноября 2008

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

У кого-нибудь есть предложения по безопасному способу решения этой проблемы?

Я подумал, что, может быть, PKI установит учетные данные и сохранит результат в БД. Затем используйте закрытый ключ для дешифрования (PHP может сделать это). Сохраните сценарии для этого вне корневого веб-каталога.

Любые мысли очень ценятся.

Ответы [ 12 ]

23 голосов
/ 04 ноября 2008

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

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

Если вам необходимо хранить расшифрованные учетные данные:

  1. Выберите хороший алгоритм шифрования - AES-256, 3DES (от даты) или шифр с открытым ключом (хотя я думаю, что это не нужно для этого использования). Используйте криптографическое программное обеспечение из авторитетного заслуживающего доверия источника - НЕ ПЫТАЙТЕСЬ СДЕЛАТЬ СВОЮ СОБСТВЕННОСТЬ, ВЫ, ПОДОБНО, ПОЛУЧИТЕ ЭТО НЕПРАВИЛЬНО.
  2. Используйте генератор случайных чисел secure для генерации ваших ключей. Слабая случайность - это причина номер один ошибок шифрования, а не алгоритмов шифрования.
  3. Храните ключи шифрования / дешифрования отдельно от базы данных в защищенном файле O / S, доступном только для профиля времени выполнения ваших приложений. Таким образом, если ваша БД взломана (например, путем внедрения SQL-кода), ваш ключ не будет автоматически уязвим, так как для этого потребуется доступ к жесткому диску в целом. Если ваша операционная система поддерживает шифрование файлов, привязанное к профилю, используйте его - это может помочь только в общих чертах (например, шифрование NTFS).
  4. Если возможно, храните сами ключи в зашифрованном виде с помощью основного пароля. Обычно это означает ваше приложение. этот пароль потребуется вводить при запуске - бесполезно указывать его в параметре из скрипта, поскольку, если ваш жесткий диск взломан, вы должны предполагать, что и файл ключа, и скрипт могут быть просмотрены.
  5. Для каждого набора учетных данных сохраните соль (в незашифрованном виде) вместе с зашифрованными данными; это используется для «заправки» шифровального шифра таким образом, что два идентичных пароля не выдают одинаковый текст шифра - поскольку это дает возможность идентифицировать пароли одинаковыми.
  6. Если имя пользователя не нужно для поиска записи учетной записи (что в вашем случае не так), зашифруйте как имя пользователя, так и пароль. Если вы шифруете оба, шифруйте их как один прогон шифрования, например,

    userAndPass = (пользовательское + ":" + пас);
    encryptInit (); * +1026 * шифровать (соль);
    шифровать (userAndPass);
    зашифрованный текст = encryptFinal ();

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

PS: я не программирую на PHP, поэтому не могу комментировать подходящие крипто-программы в этой среде.

15 голосов
/ 04 ноября 2008

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

Если вы внедрите свой собственный криптографический код, у вас не получится.

Итак, найдите хорошую реализацию, которая хорошо проверена, и используйте ее.

Возможно, здесь есть хорошая информация:

http://phpsec.org/library/

3 голосов
/ 04 ноября 2008

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

2 голосов
/ 04 ноября 2008

Я бы посоветовал вам не хранить пароли, а использовать ssh-соединение без пароля от хоста к удаленной системе, сгенерировав ключ ssh и сохранив ваш открытый ключ в файле половинных ключей удаленной системы. Тогда вам нужно будет только установить соединение во время настройки. По общему признанию, не совсем отвечая на ваш вопрос, но хранение паролей в обратимой форме - скользкий путь к нарушению безопасности imho, хотя я уверен, что умный мозг, чем мой, может сделать его безопасным.

1 голос
/ 04 ноября 2008

Один простой способ начать работу - использовать функции mysql ENCODE () и DECODE (). Я не знаю, какой алгоритм используется ниже, но он достаточно прост в использовании:

INSERT INTO tbl_passwords SET encoded_pw = ENCODE('r00t', 'my-salt-string');

и

SELECT DECODE(encoded_pw, 'my-salt-string') FROM tbl_passwords;
0 голосов
/ 04 августа 2009

Для PHP важно отметить, что шифрование AES - это , реализованное с помощью функций MCRYPT_RIJNDAEL. Не платите за не открытую реализацию, когда она доступна в PHP.

Для получения дополнительной информации см. PHP-страницу с описанием доступных шифров .

0 голосов
/ 24 ноября 2008

Просто для того, чтобы следовать предложению использовать функции кодирования и декодирования MySQL, руководство нечетко о том, как они работают:

Сила шифрования зависит от того, насколько хорош генератор случайных чисел. Для коротких строк должно хватить.

Но я бы сказал, что вместо этого вы можете использовать встроенные функции MySQL 5.0 AES ; AES_ENCRYPT() и AES_DECRYPT()

SELECT AES_ENCRYPT('secret squirrel', '12345678') AS encoded

=> ØA;J×ÍfOU»] É8

SELECT AES_DECRYPT('ØA;J×ÍfOU»] É8', '12345678') AS decoded

=> secret squirrel

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

0 голосов
/ 17 ноября 2008

Я думаю, что собираюсь исследовать компиляцию скрипта PHP с учетными данными, встроенными, на лету, из веб-приложения.

Я бы попросил учетные данные (для данного использования), а затем создал и скомпилировал новый скрипт PHP, только для этого использования. Таким образом, скрипт будет только делать то, что мне нужно, и не должен быть «читабельным». Я думаю, это звучит как самый безопасный способ сделать это.

Попробую использовать Roadsend. http://www.roadsend.com/

0 голосов
/ 04 ноября 2008

Как уже говорилось, в вашем сценарии необходимо зашифровать имя пользователя и пароль. Я бы рекомендовал вам проверить расширение mcrypt php для шифрования / дешифрования.

0 голосов
/ 04 ноября 2008

Похоже, у вас есть два способа сделать это:

1) Как вы предложили использовать алгоритм шифрования или алгоритмы, которые затем могут быть расшифрованы и использованы для аутентификации в ваших скриптах. Для этого вы можете использовать библиотеку MCrypt в PHP.

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

...