Заранее прошу прощения за входящий Wall-O-Text . Это (по крайней мере, для меня) довольно сложная проблема, над которой я довольно много подумал. Вы можете прочитать мой вопрос, а также увидеть тестовую реализацию на Ruby (очень наспех построенную, без поддержки базы данных и, вероятно, очень некрасивую) в этом GitHub Gist , если вам так хочется.
Введение
Представьте, что нужно было создать веб-систему управления паролями. Это (по крайней мере, для меня) довольно сложная проблема, над которой я довольно много подумал. Вы можете прочитать мой вопрос, а также увидеть тестовую реализацию на Ruby (очень наспех построенную, без поддержки базы данных и, вероятно, очень некрасивую) в этом GitHub Gist , если вам так хочется.
Введение
Представьте, что нужно было создать веб-систему управления паролями. Это (по крайней мере, для меня) довольно сложная проблема, над которой я довольно много подумал. Вы можете прочитать мой вопрос, а также увидеть тестовую реализацию на Ruby (очень наспех построенную, без поддержки базы данных и, вероятно, очень некрасивую) в этом GitHub Gist , если вам так хочется.
Введение
Представьте, что нужно было создать веб-систему управления паролями.
(через SSL! :) со следующими требованиями:
- Отдельные пользователи входят в систему, используя свой уникальный пароль
фраза.
- Этой парольной фразы должно быть достаточно, чтобы позволить пользователю использовать систему
эффективно (например, со смартфона и т. д.) - дело в том, что они
не должны иметь при себе файл ключа.
- Пользователи могут хранить в системе биты данных произвольной длины («записи»).
- Записи зашифрованы в базе данных таким образом, что нет
достаточно информации только в базе данных или приложении, чтобы прочитать
зашифрованные записи.
- Пользователи должны иметь возможность «делиться» записями с другими пользователями системы.
чтобы другой пользователь (пользователи) мог прочитать содержимое записи.
Я не специалист в криптографии. Подумав некоторое время, я подошел
со следующим. Мой вопрос : безопасна ли эта реализация? Я
чего-то не хватает? Если да, то можно ли реализовать указанную выше спецификацию? Или это
перебор?
База данных
База данных настроена следующим образом:
+------------------------------------------------------------------------------+
| users |
+---------+--------------+--------------+---------------+----------------------+
| salt | pub_key | enc_priv_key | priv_key_hmac | |
+---------+--------------+--------------+---------------+----------------------+
| entries |
+---------+--------------+--------------+---------------+----------+-----------+
| user_id | parent_entry | enc_sym_key | sym_key_sig | enc_data | data_hmac |
+---------+--------------+--------------+---------------+----------+-----------+
Основные варианты использования
Представьте себе двух пользователей системы, Алису и Боба.
Боб регистрируется на сайте :
- Боб вводит пароль. Этот пароль отправляется на сервер (но не
сохранено).
- Сервер генерирует случайную соль и сохраняет ее в поле
salt
.
- Сервер генерирует хэш SHA-256 пароля и соли Боба.
- Сервер генерирует Пара ключей RSA. Открытый ключ хранится как обычный
текст в поле
pub_key
. Закрытый ключ зашифрован через AES-256.
используя хэш, сгенерированный из пароля и соли Боба в качестве ключа, и
хранится в поле enc_priv_key
.
- Сервер генерирует код аутентификации сообщения на основе хэша для Боба
закрытый ключ, использующий пароль и соль Боба в качестве ключа, и сохраняет его в
поле
priv_key_hmac
.
Боб хранит запись в системе :
- Боб вводит некоторые данные, которые будут сохранены как запись вместе со своим паролем.
Эти данные отправляются на сервер.
- Сервер генерирует ключ, который будет использоваться в качестве ключа для шифрования AES-256.
- Сервер использует этот ключ для шифрования данных и сохраняет результат в
поле
enc_data
.
- Сервер генерирует код аутентификации сообщения на основе хэша для
данные, используя сгенерированный ключ, и сохраняет их в поле
data_hmac
.
- Симметричный ключ, используемый для шифрования данных, зашифрован общедоступным
ключ и хранится в поле
enc_sym_key
.
- Сервер использует закрытый ключ Боба для генерации подписи для
симметричный ключ.
Боб извлекает свою сохраненную запись :
- Боб вводит свой пароль и идентификатор записи для получения.
- Сервер генерирует SHA-256 хэш пароля и соли Боба .
- Зашифрованный закрытый ключ Боба расшифровывается с помощью шифрования AES-256 с использованием
хэш.
- Сервер проверяет, что зашифрованный закрытый ключ Боба не был
вмешательство путем проверки HMAC в
priv_key_hmac
.
- Сервер расшифровывает симметричный ключ, хранящийся в поле
enc_sym_key
используя закрытый ключ Боба.
- Сервер проверяет, что зашифрованный симметричный ключ не был подделан
с помощью проверки подписи в
sym_key_sign
с использованием открытого ключа Боба.
- Сервер дешифрует данные с помощью симметричного ключа.
- Сервер проверяет, что зашифрованные данные не были подделаны.
путем проверки HMAC, хранящегося в поле
data_hmac
.
- Сервер возвращает расшифрованные данные Бобу.
Боб делится записью с Алисой :
- Боб хочет, чтобы Алиса чтобы иметь доступ к записи, которой он владеет. Он входит в свой
пароль и идентификатор записи для совместного использования.
- Данные для записи дешифруются с использованием метода в "Боб получает
его сохраненная запись »
- Новая запись создается для Алисы таким же образом, как и в« Боб хранит
запись в системе »со следующими исключениями:
- Для записи
parent_entry
задана запись Боба.
- Подпись для симметричного ключа вычисляется с использованием частной
ключ (поскольку закрытый ключ Алисы недоступен для Боба).
- Когда Алиса обращается к этой новой записи, наличие ненулевого
parent_entry
заставляет систему использовать открытый ключ Боба для проверки
подпись (поскольку для ее создания использовался его закрытый ключ).
Боб изменяет данные в своей общей записи :
- Боб решает изменить данные в записи, которой он поделился с Алисой. Боб
указывает идентификатор записи, которую необходимо изменить, и новые данные, которые она должна содержать.
- Система перезаписывает данные, созданные в «Боб сохраняет запись в
system. "
- Система находит каждую запись с
parent_entry
, равной записи
который был только что изменен, и для каждого из них перезаписываются данные, созданные в
«Боб делится записью с Алисой».
Анализ
Преимущества:
- Невозможно расшифровать какие-либо данные из базы данных без
пароль пользователя, владеющего данными, поскольку закрытый ключ необходим для
расшифровать данные зашифрованы паролем пользователя, и этот пароль
(и его хэш) не хранятся в базе данных.
- Если пользователь хочет изменить свой пароль, только его зашифрованные личные
ключ необходимо регенерировать (расшифровать закрытый ключ старым
пароль / хэш, затем повторно зашифруйте его новым паролем / хешем).
- Общие записи хранятся как фактические отдельные записи в базе данных,
поэтому нет необходимости делиться ключом между несколькими пользователями / группами пользователей.
Недостатки / проблемы (которые я могу придумать):
- Если общая запись изменена, система должна повторно зашифровать каждый дочерний элемент
запись; при большом количестве пользователей, обменивающихся данными, это потенциально может
быть дорогостоящим в вычислительном отношении.
- Общие записи зависят от открытого ключа родительского пользователя для подписи
проверка. В случае удаления пользователя или изменения его ключа подписи
недействительны.
Повторяется из введения: мой вопрос: эта реализация
безопасный? Я что-то пропустил? Если да, то можно ли реализовать эту спецификацию?
Или это излишество?
Спасибо, что так долго не торопились. Мне интересно ваше мнение! Я на правильном пути или полный придурок? ВАМ РЕШАТЬ! :)