Где я должен хранить ключ шифрования для php?

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

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

Как лучше всего это сделать?

Могу ли я изменить массив $_SERVER для хранения информации между запросами? Могу ли я каким-то образом сохранить ключ с помощью apache? Может общая память?


person Levi    schedule 20.07.2011    source источник
comment
Хотя я думаю, что сама ваша идея плоха, dev.mysql .com/doc/refman/5.0/en/memory-storage-engine.html   -  person Dan Grossman    schedule 21.07.2011
comment
Что произойдет, если машина самопроизвольно перезагрузится (или вам нужно будет ее перезагрузить). Ключ просто исчезает? Или приложение находится в автономном режиме, пока администратор не сможет найти где-нибудь ключ из резервной копии и ввести его вручную. Это может быть медленным процессом.   -  person Kibbee    schedule 21.07.2011
comment
Что произойдет, если администратор случайно загрузит неправильный ключ или поврежденный ключ? Пока кто-то не заметит, вы храните данные, которые никогда не будут восстановлены, и вы не будете знать, какие данные были созданы с помощью плохого ключа, а какие — хорошего, за исключением случаев, когда вы пытаетесь расшифровать каждую часть и выяснить, какие из них нельзя восстановить.   -  person Dan Grossman    schedule 21.07.2011
comment
@genesis: я согласен, что злоумышленник все еще может просматривать содержимое памяти, но мне нужно сотрудничать с ИТ-отделом моего клиента, и они не хотят, чтобы это сохранялось в файле.   -  person Levi    schedule 21.07.2011
comment
Да, насколько я понимаю, у этого есть целая куча плохих побочных эффектов.   -  person Kibbee    schedule 21.07.2011
comment
@Кибби: Точно. У их клиентов есть ИТ-отдел, который согласен с этой процедурой.   -  person Levi    schedule 21.07.2011
comment
Нет, Мэтт. $_SESSION хранит пары "ключ-значение" на диске, и они доступны только одному пользователю с соответствующим файлом cookie сеанса, а не всем пользователям приложения.   -  person Dan Grossman    schedule 21.07.2011
comment
@Dan Grossman: Очень хороший момент... Я не думал об этом   -  person Levi    schedule 21.07.2011
comment
@ Matt H: ключ распространяется на все приложение   -  person Levi    schedule 21.07.2011
comment
@Dan Независимо от того, где вы храните ключ, сервер должен проверять его при запуске. (Вы можете проверить ключ, расшифровав содержимое ранее зашифрованного поля, значение которого известно.)   -  person jdigital    schedule 21.07.2011
comment
Лучше не использовать AES, так как многие серверы хранят свои базы данных на другом сервере, что означает передачу большего количества данных вне вашего контроля. Лучше зашифровать в PHP перед отправкой в ​​SQL. Используйте openssl или еще лучше готовую современную популярную библиотеку шифрования.   -  person Pixel    schedule 26.04.2018
comment
примечание, поскольку сегодня в ленте появился этот вопрос: шифрование AES в MySQL не подходит для шифрования. Если вам нужны БЕЗОПАСНЫЕ данные, вам нужно зашифровать их вне MySQL, поэтому MySQL знает только зашифрованные данные и не может экстраполировать открытый текст. MySQL может легко иметь различные средства отслеживания действий и событий, которые будут регистрировать расшифрованные данные в файлах журнала сервера, что приведет к серьезному нарушению безопасности в случае взлома MySQL (например, сервер MySQL может быть скомпрометирован, а сервер PHP, который с ним взаимодействует, может оставаться в безопасности) .   -  person Martin    schedule 08.07.2021


Ответы (5)


Вместо того, чтобы полагаться на MySQL AES для шифрования, почему бы не использовать собственную схему шифрования PHP openssl (расширение PECL). Для этого требуются закрытый и открытый ключи, открытый для шифрования и закрытый для расшифровки, а ключи можно хранить в разных местах.

person Explosion Pills    schedule 20.07.2011

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

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

Мне понравился этот подход, потому что:

  1. Ключ не хранится в файловой системе, что предотвращает проблемы с утилизацией оборудования в конце срока службы и от посторонних глаз системных администраторов.
  2. Код приложения не может получить доступ к ключу (кроме как при его вводе), поэтому единственное место, где он когда-либо будет находиться, — это процесс базы данных.
  3. Вся логика для шифрования/дешифрования встроена в SQL-запросы, поэтому не нужно беспокоиться о том, что код приложения делает это правильно — удобно для обслуживания.
person Levi    schedule 01.09.2011
comment
Что делать, если сервер падает? Таблица в памяти с ключом будет потеряна, и ваши данные больше не будут доступны? - person PiTheNumber; 23.09.2015

Одна из возможностей — создать RAM-диск и сохранить там ключ.

person Kibbee    schedule 20.07.2011

Самое безопасное место для хранения любого ключа шифрования — на сервере, а не в базе данных, и убедитесь, что он принадлежит пользователю root и не может быть прочитан другими.

person serialworm    schedule 20.07.2011
comment
и как клиент получит к этому доступ? Кстати, база данных тоже на СЕРВЕРЕ;) - person genesis; 21.07.2011
comment
Клиенту не нужен доступ к нему. Предположение автора о том, что повторная загрузка ключа администратором при каждом запуске приложения является хорошей идеей, является плохой идеей. Во-первых, если администратор случайно ошибется с ключом или один раз загрузит неправильный файл, все данные, хранящиеся в нем, не будут восстановлены, и никто не узнает, какие записи были зашифрованы каким ключом. - person Dan Grossman; 21.07.2011
comment
@serialworm Вы предложили убедиться, что только root может прочитать файл, но php, вероятно, не будет работать от имени пользователя root ... - person Dan Grossman; 21.07.2011
comment
Хорошая точка зрения. Я заметил, что он упомянул, что хотел бы избежать хранения ключей на сервере, но я знаю об опасностях хранения ключей в базе данных. - person serialworm; 21.07.2011
comment
Еще один хороший момент. Я согласен с этим. Однако я по-прежнему утверждаю, что наличие файла, принадлежащего пользователю веб-сервера (apache) или кому-то еще, будет более безопасным, чем хранение в базе данных. - person serialworm; 21.07.2011
comment
Из-за точки зрения Дэна, что я рискую создать невосстановимые зашифрованные данные, если ИТ-специалист загрузит неправильный ключ, я собираюсь предложить, чтобы ключ хранился в файловой системе. Спасибо за все ответы! - person Levi; 21.07.2011
comment
@Levi См. мою точку зрения выше. У вас та же проблема, даже если ключ хранится в файловой системе (вероятность намного ниже, но файл ключа все равно может быть поврежден или случайно заменен). Вы всегда должны проверять ключ при запуске, независимо от того, где он хранится. - person jdigital; 21.07.2011
comment
Я собираюсь сохранить в базе данных зашифрованное поле, содержимое которого мне известно — назовем это значение $special. Когда я устанавливаю приложение, я выберу ключ по умолчанию для шифрования $special. Когда приложение запущено и администратор пытается загрузить ключ шифрования, оно гарантирует, что $special расшифровывает известное содержимое. Чтобы изменить ключи, мне просто нужно сохранить обновленное шифрование поля $special. - person Levi; 21.07.2011
comment
Еще одна вещь, о которой я забыл упомянуть, заключается в том, что эти данные могут храниться кратковременно, поэтому текущие данные базы данных могут быть удалены после изменения ключа шифрования. - person Levi; 21.07.2011
comment
Я бы поставил вышеизложенное в ответ, но мне не хватает репутации - person Levi; 21.07.2011
comment
Весь смысл шифрования AES заключается в том, чтобы сделать ваши данные нечитаемыми, если ваша БД будет скомпрометирована. Обычно я вижу ключи и соли, хранящиеся непосредственно в PHP внутри файла конфигурации или заголовков. Обоснование этого заключается в том, что ЕСЛИ кто-то смотрит на ваш PHP, вы уже проиграли, независимо от того, как вы его храните, потому что им просто нужно найти вызов функции, который вы написали для дешифрования. Если они найдут ваш ключ по пути, это просто ущерб, который уже был неизбежен. - person Nosajimiki; 27.03.2018

Напишите файл конфигурации php и сохраните его в своем домашнем каталоге. Разрешить доступ к нему только php.

$cryptKey = "aac1ebadcfabdef72376acd" ;

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

person David    schedule 07.07.2021