Подтвердить что ты не робот

Зашифрованные столбцы MySQL

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

Как зашифровать столбец данных с помощью InnoDB, чтобы никто, кроме пользователя, не мог прочитать данные? Я думал о чем-то вроде использования одной из функций шифрования MySQL (скажем, AES) с ключом, основанным на хеше, вычисленном из пароля пользователя.

Есть ли у кого-нибудь какие-либо указания на то, как я могу это сделать? Я на правильном пути?

Один из ответов ниже

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

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

4b9b3361

Ответ 1

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

Другим подходом было бы зашифровать данные специальным ключом приложения, соленым с некоторыми данными, специфичными для пользователя. Однако перед вами возникает другая проблема: как безопасно хранить ключ приложения. На этот вопрос я не знаю простого ответа, но сохранить его в исходном коде, вероятно, достаточно хорошо, если вы боитесь, что ваши данные базы данных могут быть скомпрометированы, но не сам исходный код, например. если ваша база данных хранится за пределами сайта (подумайте, что Amazon S3).

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

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

INSERT INTO secure_table VALUES (
  1,
  AES_ENCRYPT(
    'plain text data',
    CONCAT(@application_password, @user_password))
);

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

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

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

Ответ 2

Чтобы прояснить один из ответов, упомянутых в вопросе: "user/app key" - это случайный сгенерированный закрытый ключ, который используется для шифрования данных. Частный ключ никогда не изменяется (если только он не скомпрометирован). Вы шифруете и сохраняете закрытый ключ с паролем. Поскольку закрытый ключ намного меньше данных, гораздо дешевле изменить пароль: вы просто расшифровываете закрытый ключ со старым паролем и заново шифруете его с помощью нового пароля.

Ответ 3

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

extra password может быть побитовым с другим salt-like string внутри исходного кода. Вместе он может сформировать симметричный ключ доступа для дешифрования private key, хранящегося в базе данных (который никогда не изменится). После private key расшифровывается с помощью extra password, закрытый ключ может дешифровать и read все данные в db. Закрытый ключ может быть сохранен как переменная сеанса.

public key, как следует из названия, может находиться в виде простой текстовой строки в db. Когда вам нужно write to db, используйте открытый ключ для шифрования данных.

Вы можете регулярно предоставлять пользователям новый extra password и повторно шифровать статический private key, за которым следует xor'ing с salt-like string.

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

Ответ 4

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

Ответ 5

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

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

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

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

Ответ 6

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

Ключ должен быть зашифрован обратимым образом, чтобы он мог быть расшифрован используя pass1 и повторно зашифрованный с помощью pass2.

Подводя итог:

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

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

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

Ответ 7

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