MySQL зашифрованные столбцы - PullRequest
11 голосов
/ 26 октября 2008

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

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

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

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

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

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

Ответы [ 7 ]

9 голосов
/ 26 октября 2008

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

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

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

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

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

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

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

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

2 голосов
/ 27 октября 2008

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

1 голос
/ 10 июня 2013

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

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

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

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

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

0 голосов
/ 28 апреля 2009

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

0 голосов
/ 27 октября 2008

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

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

Подведем итог:

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

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

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

0 голосов
/ 26 октября 2008

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

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

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

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

0 голосов
/ 26 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...