Вопрос или проблема
Хранение секрета сервера в пользовательском идентификаторе и ключе доступа
Я хочу реализовать поддержку ключей доступа как полную замену паролям, но у меня есть некоторые серверные данные, которые все еще нужно зашифровать для конкретного пользователя таким образом, чтобы их нельзя было расшифровать или воспроизвести на стороне сервера без пользовательской сессии. В текущей системе, когда пользователь входит в систему, мы генерируем симметричный ключ шифрования с их паролем, используем его для расшифровки закрытого ключа и используем этот закрытый ключ для шифрования/расшифровки дальнейших данных, специфичных для ключей шифрования.
Цели этой системы:
- Исключить пароли
- Обеспечить надежную связь между данными, зашифрованными на сервере (которые никогда не доступны пользователю напрямую), и их ключом доступа
- Обеспечить некоторую неполучаемость при использовании их ключа, никогда не сохраняя ключи на стороне сервера. В основном, должно быть невозможно расшифровать или воспроизвести любое действие пользователя, если пользователь не присутствует.
- Обеспечить, чтобы данные, зашифрованные на сервере, были бесполезны без присутствия ключа доступа пользователя. (Случай утечки данных)
Угрозы:
- Утечка данных на стороне сервера
- Пользователь пытается утверждать, что он не выполнил действие, когда на самом деле это так
- Нападающий получает доступ к учетным данным пользователя, так что он может расшифровать ассиметричный ключ пользователя и использовать его в сочетании с утечкой данных
- Работающее серверное программное обеспечение не считается угрозой
Идея заключается в том, чтобы использовать двоичный идентификатор пользователя, связанный с ключом доступа, для хранения симметричного ключа, который будет функционально подобен паролю пользователя в приведенном выше потоке (но не используется для аутентификации, просто используются подписи WebAuthn для этого). Этот ключ никогда не раскрывается пользователю (вместо этого отображается удобное для пользователя название) и ограничен стороной, на которую он был создан, так что его никогда не следует передавать стороне, которая не имеет к нему доступа. Процесс будет генерировать 256-битный ключ, который будет зашифрован с помощью серверного ключа, на случай, если какая-то ошибка в экосистеме WebAutn приведет к тому, что этот ключ случайно будет раскрыт некорректной стороне (пользователь сам по себе не считается угрозой в модели безопасности). Этот ключ и 64-битный идентификатор сервера будут упакованы в идентификатор пользователя ключа доступа и сохранены с пользователем. Система будет использовать обнаруживаемые ключи доступа для входа пользователя в систему и доступа к этому идентификатору.
На стороне сервера процесс аутентификации будет выглядеть так:
- Использовать обнаружение ключей доступа для выполнения сессии аутентификации, что приведет к созданию подписи для вызова и идентификатора пользователя.
- Использовать идентификатор контекста из идентификатора пользователя для поиска записи крипто-контекста и расшифровать симметричную часть ключа идентификатора пользователя с помощью серверного ключа из шага настройки.
- Использовать серверный секрет для HMAC идентификатора пользователя в серверный токен идентификатора пользователя для поиска открытого ключа пользователя. Существует параллельное отображение от этого токена к реальному идентификатору пользователя в системе хранения пользователей.
- Завершить аутентификацию в соответствии со стандартом WebAuthn с открытым ключом пользователя.
- Расшифровать закрытый ключ пользователя из базы данных с помощью симметричного ключа, полученного выше, и забыть этот ключ. Поместить ассиметричный ключ в зашифрованный и ограниченный по времени куки сессии пользователя для его последующего использования. (Сессии шифруются с использованием ключа, который хранится в памяти сервера и автоматически обновляется ежедневно и никогда не сохраняется)
Восстановление ключа доступа будет использовать случайно сгенерированный код, который в конечном итоге будет оберткой для ассиметричного ключа так же, как это делает код размещенного ключа доступа. Если пользователь потеряет этот код, то ему не повезло.
Это плохая идея? Есть ли что-то, что я упускаю, что делает безопасность этой системы недействительной?
Ответ или решение
Ваш вопрос касается внедрения поддержки пасскода в качестве полной замены паролей, при этом необходимо обеспечить надежную связь между зашифрованными данными на сервере и используемым пользователем пасскодом. Рассмотрим ваше решение более подробно и определим, придерживается ли оно заданных вами целей и недостатков.
Цели системы
-
Исключение паролей: Использование пасскодов и аутентификация через WebAuthn — правильный путь к безопасной аутентификации без паролей.
-
Надежная связь между серверными данными и пасскодом: Хранение симметричного ключа в уникальном идентификаторе пользователя обеспечивает значимую связь.
-
Нереализуемость действий без присутствия пользователя: Использование временно хранимой сессии и удаление симметричного ключа после его использования минимизирует риски.
- Ненадежность серверных данных без пасскода: Упаковка симметричного ключа и серверного идентификатора в пользовательский идентификатор — правильный подход для обеспечения утечки данных.
Угрозы и риски
-
Утечка данных на сервере: Ваше решение реализует контроль доступа к зашифрованным данным на сервере, так что в случае взлома зашифрованные данные останутся бесполезными без пасскода.
-
Отказ пользователя от действий: Ваше предложение по использованию HMAC в процессе аутентификации поможет подтвердить, что действие было выполнено настоящим пользователем.
-
Доступ злоумышленника к ключам: Система, которая не сохраняет.keys и хранит их только в памяти сервера, сводит к минимуму риск недобросовестного использования.
- Безопасность серверного ПО: Если ваше программное обеспечение поддается атакам, оно может стать уязвимым местом, поэтому следует применять практики безопасной разработки.
Плюсы и минусы
Плюсы:
- Ваше решение устраняет необходимость в паролях и базируется на современных методах аутентификации.
- Шифрование симметричного ключа предотвращает его несанкционированный доступ даже в случае утечек данных.
Минусы:
- Потребность в сохранении и защите сервера и его конфиденциальной информации. Даже конечная надежная система требует регулярного аудита.
- Уникальный идентификатор пользователя, содержащий симметричный ключ, может быть подвержен атакам. Лучше предусмотреть дополнительные меры защиты, например, хранение идентификаторов в защищенном виде (например, с помощью маскирования или хеширования).
Заключение
Ваше предложение выглядит достаточно обоснованным и безопасным с точки зрения ключевых аспектов безопасности и удобства использования. Однако, важно помнить о потенциальных уязвимостях, связанных с некорректной реализацией или использованием технологии, а также преимуществе регулярных аудитов и тестов на проникновение.
Также стоит рассмотреть чёткие механизмы восстановления доступа и тщательное планирование сценариев, позволяющих пользователям без труда восстановить свои пасскоды в случае их потери. Это минимизирует риск того, что пользователи могут потерять доступ к своим данным, и сделает вашу систему более удобной.