Хранение симметричного ключа для остальной части базы данных в зашифрованном виде в самой базе данных
В продолжение моего вопроса мне теперь нужно безопасно хранить симметричный ключ. После просмотра параметров звучит так, что это может быть хорошим вариантом:
Настроить:
В БД есть таблица с двумя полями
php_key - stores a symmetrically encrypted symmetric key that is used for OTHER tables
php_key_hash - stores a hmac of the symmetric key
другие таблицы (как упоминалось в другом посте):
last_name - symmetrically encrypted value encrypted with key after being unencrypted from php_key
last_name_hash - hmac of last_name
Логин / Безопасная защита ключа:
1) Пользователь входит в систему - (несвязанный) пользователь / пароль просто сохраняется в БД (пароль - это hmac)
2) После входа в систему пользователю предоставляется экран, на котором ему необходимо ввести другой пароль - этот пароль будет доступен всем сотрудникам компании (так легко запомнить только 5 сотрудников). Позволяет назвать этот ключ1.
3) Этот пароль выполнен hmac и сравнивается с php_key_hash в БД.
Если это не удается, я могу просто ошибиться здесь.
4) Если он совпадает, то нажмите php_key, расшифруйте его, используя тот же пароль, сохраните в переменной сессии.
В этот момент ключ хранится в памяти на сервере и будет уничтожен, когда пользователь выйдет из системы. Позволяет назвать этот ключ2.
После этого происходит нормальная расшифровка полей, как в другом посте
Это кажется мне действительно безопасным, потому что
1) ключ2 хранится на сервере, отличном от веб-сервера
2) ключ2 сам по себе зашифрован - он никогда не сохраняется в виде простого текста
3) ключ1 находится не там, где в коде, в файловой системе или в базе данных - он известен только в умах сотрудников
4) Вы должны войти на сайт в основном дважды (один с вашим логином, снова с key1)
5) Использование переменных сеанса означает, что ключ 2 хранится только в памяти и только на сервере и уничтожается после окончания сеанса
6) Я могу просто повторно ввести key1 в любое время, если нам нужно изменить фразу-пароль - например, если сотрудник уходит или мы думаем, что он скомпрометирован
Потенциальные проблемы AKA Мои вопросы (наконец)
Во-первых, я ни в коем случае не эксперт по безопасности, поэтому мне просто нужно мнение кого-то, кто лучше меня по безопасности:)
1) Я потенциально храню зашифрованный симметричный ключ (key2) в той же базе данных, где он будет использоваться для расшифровки других полей. Я не думаю, что это проблема, так как она сама зашифрована?
2) Хранение симметричного ключа (key2) в переменной сеанса - потенциальные проблемы с людьми, работающими в оперативной памяти? Возможно, было бы лучше просто сохранить key1 в переменной сеанса и затем каждый раз проходить двойное дешифрование (но, вероятно, медленно)? Я слишком осторожен?
1 ответ
ОК, я думаю, теперь я понимаю, что вы имеете в виду. Я полагаю, вы имеете в виду:
key1 = PBKDF2(password, salt, many_iterations)
php_key_hash = HMAC(key1, salt)
Когда вы говорите HMAC в качестве пароля, я предполагаю, что вы имеете в виду PBKDF2 со многими итерациями (например, несколько секунд). В любом случае, чтобы ответить на ваши 2 вопроса:
1) Сохранение key2
зашифрован прямо рядом с данными, зашифрованными key2
все в порядке. по факту AWS KMS
работает таким образом, за исключением того, что они используют разные key2
для каждого шифрования. Если один key2
скомпрометирован, будут скомпрометированы только его соответствующие данные (не вся база данных). И это делает поворот ключа проще.
2) Если вы продолжаете key1
в оперативной памяти вместо key2
, это не поможет: если кому-то удастся получить key1
из оперативной памяти, вы можете предположить, что они имеют доступ к php_key
из базы данных также и сможет расшифровать key2
, Если вы хотите предотвратить эту проблему и не хотите иметь ключи в оперативной памяти, вы должны рассмотреть HSM (и key2
на равнине никогда бы не покинул HSM). Без HSM, key2
должно быть в оперативной памяти в какой-то момент.