Вопрос или проблема
Я создаю веб-сайт на PHP, используя MySQL в качестве базы данных для системы управления событиями. Я хочу хранить данные пользователей, чтобы, когда они регистрируются на событие, им нужно было просто подтвердить информацию и отправить, а не вводить данные снова и снова.
Я практически полный новичок, когда дело касается шифрования. Я дважды хешировал пароли (один раз на клиенте, один раз на сервере) и хранил их в базе данных, но я хотел бы зашифровать данные пользователей, такие как электронные адреса, адреса, аллергии и т.д. Я прочитал о симметричном и асимметричном шифровании, и не знаю, с чего начать, где хранить ключи, достаточно ли будет только симметричного и т.д. Любая помощь будет очень полезной!
Алгоритм шифрования
Для хранения конфиденциальных данных в базе данных, которые будут извлечены и отображены пользователю позже, идеально подходит симметричное шифрование. Оно более простое и эффективное, чем асимметричное (также известное как шифрование с открытым ключом), и распределение ключей не является проблемой в вашем случае, так что нет необходимости в асимметричном или гибридном шифровании.
Хорошим алгоритмом шифрования для использования будет AES с 256-битным ключом в режиме GCM (AES-256-GCM). AES является стандартом NIST, широко используется и выдержал испытание временем. 256-битный ключ обеспечивает уровень безопасности 128 бит, что, как правило, считается достаточным для большинства современных систем. GCM — это режим аутентифицированного шифрования, что означает, что если злоумышленник попытается подделать ваши данные, GCM обнаружит это при расшифровке. GCM также позволяет вам включать «ассоциированные данные», чтобы связать шифротекст с его контекстом и предотвратить атаки, когда шифротекст «вырезается и вставляется» в другой контекст; например, вы можете использовать идентификатор пользователя в качестве ассоциированных данных.
Векторы инициализации
Рекомендуется использовать 12-байтовый вектор инициализации для шифрования в режиме GCM. Критически важно использовать уникальный IV для каждой операции шифрования с одинаковым ключом — простой способ сделать это — использовать криптографически безопасный генератор случайных чисел (например, random_bytes). IV не является секретом, поэтому вы можете хранить его вместе с шифротекстом; он вам понадобится для расшифровки данных.
Ключи шифрования
256-битный ключ шифрования также должен генерироваться с помощью криптографически безопасного генератора случайных чисел и храниться надежно. В идеале ключ будет создан в специализированной системе управления ключами (KMS) и храниться там. Затем вы можете использовать этот ключ в качестве ключа шифрования ключа (KEK) для шифрования одного или нескольких ключей шифрования данных (DEK), которые затем можно использовать для шифрования фактических данных. Поскольку ваш DEK был зашифрован, вы можете хранить его вне KMS; я предпочитаю хранить его в исходном коде, чтобы его можно было версионировать и легко получить доступ приложению.
Ротация ключей
Вы должны планировать ротацию своих ключей. Если вы зашифруете слишком много данных под одним ключом, вы рискуете столкнуться с «коллизиями», которые могут разрушить безопасность шифровальной системы. Например, с 12-байтовым IV вы можете начать ожидать коллизии IV после 248 операций шифрования. Подобная проблема возникает и с коллизиями в блоках шифротекста. Консервативный подход заключается в том, чтобы ротировать ваш DEK до 221 операций шифрования или 64 ГБ данных.
Предполагая, что у вас нет множества DEK, вы можете установить ротацию вашего KEK раз в год или два.
Чтобы упростить ротацию ключей, вы можете пометить свой шифротекст идентификатором ключа, который его зашифровал, и поддерживать «кириллицу» ключей. Таким образом, когда вы хотите ротировать ключ, вы просто создаете новый ключ, добавляете его в ключевую цепочку и начинаете шифровать новые данные с помощью этого ключа. Операции расшифровки могут по-прежнему использовать ключ, который использовался для шифрования данных.
Вы также должны иметь процесс для ротации ключа и повторного шифрования всех ваших данных в случае компрометации ключа или его криптографического разрушения.
Наконец, вам понадобится удобная для пользователя библиотека шифрования, которая справляется с максимально возможным количеством вышеуказанных моментов и делает сложнее для вас допустить ошибки.
Ответ или решение
Для шифрования и хранения пользовательских данных в вашем PHP-приложении с использованием MySQL в качестве базы данных, предлагаю несколько шагов и рекомендаций, чтобы обеспечить безопасность ваших данных.
Выбор алгоритма шифрования
Для хранения конфиденциальной информации, такой как электронные адреса, адреса проживания и аллергии, оптимальным будет использование симметричного шифрования. Наиболее подходящим алгоритмом является AES (Advanced Encryption Standard) с длиной ключа 256 бит в режиме GCM (Galois/Counter Mode). AES является стандартом NIST, широко используется и считается надежным. 256-битный ключ обеспечивает уровень безопасности 128 бит, что достаточно для большинства современных систем. Режим GCM также предоставляет возможность аутентификации данных, что позволит обнаруживать любое вмешательство в зашифрованные данные.
Инициализационные векторы
Для режима GCM рекомендуется использовать инициализационный вектор (IV) длиной 12 байт. Важно, чтобы для каждой операции шифрования использовался уникальный IV. Для этого можно использовать криптографически безопасный генератор случайных чисел, например, функцию random_bytes
в PHP. IV не является секретом и его можно хранить вместе с зашифрованными данными, так как он необходим для последующего расшифрования.
Хранение ключей шифрования
Ключ шифрования должен генерироваться с помощью криптографически безопасного генератора случайных чисел и храниться безопасно. Идеальный подход — использовать специализированную систему управления ключами (KMS). Ключ генерируется в KMS и может использоваться как ключ шифрования (KEK) для шифрования одного или нескольких ключей шифрования данных (DEK), которые непосредственно используются для шифрования пользовательских данных. DEK можно хранить вне KMS, например, в коде вашего приложения, где его можно легко версионировать и получать доступ.
Ротация ключей
У вас должна быть запланирована ротация ключей. Если вы будете шифровать много данных одним и тем же ключом, это может привести к "коллизиям", что потенциально ослабит безопасность. Чтобы избежать этого, рекомендуется менять DEK не реже чем после 2^21 операций шифрования или 64 ГБ данных. KEK можно менять раз в год или два.
Для упрощения процесса ротации ключей вы можете тегировать зашифрованные данные идентификатором ключа, использованного для шифрования, и поддерживать "ключевую кольцевую" структуру. При смене ключа вы просто создаете новый ключ и начинаете использовать его для шифрования новых данных, сохранив возможность расшифровывать старые данные.
Проблемы с компрометацией ключей
В случае компрометации ключа или его устаревания вы должны иметь процесс для ротации ключа и повторного шифрования всех данных. Это обеспечит защиту в случаях потенциальных угроз.
Использование удобной библиотеки шифрования
Рекомендуется использовать надежную библиотеку для шифрования, которая будет упрощать реализацию всех перечисленных шагов и минимизировать вероятность ошибок с вашей стороны. Библиотеки, такие как OpenSSL или Libsodium для PHP, могут значительно упростить вам жизнь в этом вопросе.
Заключение
Шифрование и хранение пользовательских данных требует тщательного планирования и соблюдения лучших практик безопасности. Использование AES-256-GCM, правильное управление и хранение ключей, а также регулярная ротация ключей помогут вам создать безопасную и надежную систему для хранения пользовательской информации. Не забывайте также о регулярных проверках и обновлениях вашей системы безопасности.