Безопасность: Насколько уязвима эта схема аутентификации / шифрования? - PullRequest
2 голосов
/ 16 февраля 2011

У меня есть игра клиент-сервер, где клиент подключается к серверу и остается подключенным в течение игры (около 5-60 минут).

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

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

Так как я все равно хочу сохранить отдельный сервер входа, моя идея такова:

  1. Клиент отправляет HTTPS-запрос на сервер входа с учетными данными (или регистрационными данными)
  2. Сервер регистрации собирает информацию о пользователе и генерирует временный ключ шифрования сеанса RC4
  3. Информация о пользователе + сеанс RC4 + метка времени + дайджест (я могу рассчитывать на синхронизацию по времени на обоих серверах) с секретным симметричным ключом, разделяемым между игровым сервером и сервером входа.
  4. Упакованные данные + ключ шифрования сеанса RC4 + IP-адрес на игровой сервер отправляются в ответ на запрос HTTPS клиенту.
  5. Клиент открывает соединение с игровым сервером, отправляет исходное незашифрованное приветственное сообщение с зашифрованной пользовательской информацией в качестве полезной нагрузки.
  6. Игровой сервер распаковывает данные, упакованные в (3). Теперь он знает пользователя и ключ шифрования RC4, который предполагается использовать.
  7. Если отметка времени показывает, что учетные данные для входа истекли, клиенту возвращается ошибка (которая затем должна получить новую информацию). Если расшифрованные данные пользователя не могут быть проверены с помощью дайджеста, возвращается другая ошибка.
  8. Если все проверено нормально, сервер отправляет незашифрованный LOGIN_OK и начинается зашифрованная связь RC4.

Возможные проблемы безопасности:

  • Игровой сервер на 100% доверяет расшифрованной информации пользователя. Это делает серверы полностью отсоединенными, что приятно, но если ключ скомпрометирован, пользователи могут полностью подделать информацию о своих пользователях. Это можно несколько ослабить, вращая эти клавиши, чтобы каждый день или месяц получал новый ключ. И игровые серверы, и серверы входа могут получить это с третьего сервера, который управляет их ключами. Это может быть излишним, так как: а) в случае взлома, когда исходный код отображается на серверах, они могут быть перезапущены с новым ключом; б) достаточно хороший ключ + шифрование должно затруднить атаки методом перебора (предложения по алгоритму). ?)

  • RC4 не самый безопасный алгоритм, но я обязательно выбрасываю первые 512 байтов или около того, и каждый ключ действителен только в течение ограниченного времени, например, 24ч.

  • Кажется, что человек-посредник не восприимчив к тому, что я вижу: SSL защищает ключ сеанса RC4, в (5) ключ сеанса RC4, отправляемый на игровой сервер, также шифруется. Все, что возможно - это DoS и снова вызвать запрос пользователя на ключ. Если данные в (2) кэшируются до истечения срока их действия, это не должно создавать новый пакет.

  • Шифрование в (3) можно улучшить, добавив в ключ случайные биты. Эти случайные биты отправляются вместе с зашифрованным пакетом и представляются игровому серверу в (5). В (6) игровой сервер добавляет эти случайные биты к своему ключу и использует результат для расшифровки данных. Таким образом, злоумышленник не может видеть, когда изменяются упакованные данные.

Есть ли какие-либо уязвимости, которые я здесь пропускаю?

Сводка созданных полезных нагрузок:

  • Клиентские учетные данные (защищены SSL), отправленные на сервер входа
  • Информация о пользователе + временная метка + временный ключ сеанса игрового сервера + дайджест, зашифрованный сервером входа в систему с использованием секретного ключа, предоставленного игровому серверу, который предоставляется клиенту, который - без его изменения - передает его на игровой сервер.Должно быть стойким к отпуску, потому что: а) клиент не знает секретный ключ; б) имеет временную метку, чтобы избежать повторной отправки одних и тех же данных; в) дайджест для проверки правильности шифрования содержимого
  • временный ключ сеанса игрового сервера, отправленный сервером входа в систему.клиенту вместе с зашифрованной полезной нагрузкой.Защищено SSL.
  • Пакет входа на сервер игрового сервера клиента, состоит из зашифрованного пакета, полученного сервером регистрации.

Сводка ключей шифрования:

  • Временный ключ сеанса игрового сервера: случайным образом генерируется сервером входа для зашифрованного игрового сервера <-> связи с клиентом.Генерируется сервером входа в систему, передается клиенту и игровому серверу.
  • Секретный ключ шифрования информации пользователя.Распределяется между игровым сервером и сервером входа в систему, используется для передачи информации о пользователе на игровой сервер с клиентом в качестве мессенджера.Клиент не обладает этим ключом.

Ответы [ 5 ]

2 голосов
/ 17 февраля 2011

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

2 голосов
/ 16 февраля 2011

Прежде всего, я бы не использовал RC4. Существуют как более быстрые, так и более безопасные потоковые шифры, поэтому, если вы управляете как клиентом, так и сервером, вы, вероятно, сможете добиться большего успеха, чем RC4. Сброс только 512 байт может оказаться недостаточным для атаки Флюрера, Мантина и Шамира, но даже если вы отбросите больше байтов, есть также атака Кляйна и т. Д. Я не знаю, стоит ли эта проблема.

Во-вторых, убедитесь, что генерируемые вами ключи случайны. Я знаю, это кажется очевидным, но для примера см .: http://www.debian.org/security/2008/dsa-1571

Но настоящая проблема заключается в следующем: «Игровой сервер на 100% доверяет информации, которую он расшифровал. Это делает серверы полностью отсоединенными, что приятно, но если ключ скомпрометирован, пользователи могут полностью подделать информацию о своих пользователях. «

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

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

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

Вы никогда не должны доверять клиенту. Вы должны хранить данные клиента на стороне сервера и сопоставлять их с ключом или подписывать данные и проверять их или использовать HMAC и т. Д., Потому что если игровой сервер на 100% доверяет пользовательской информации, то у вас будут проблемы раньше или позже. Там практически нет пути.

1 голос
/ 25 февраля 2011

Я также опубликовал сообщение на sci.crypt и постараюсь обобщить предложенные изменения (насколько я понимаю) ниже, на случай, если они могут быть интересны.

Шаг 1: Клиент отправляет HTTPS-запрос серверу входа в систему с учетными данными

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

Шаг 3: Информация о пользователе + сеанс RC4 + метка времени + дайджест

Используйте алгоритм шифрования, который обеспечивает целостность, вместо использования дайджеста в явном виде.Например, AES-GCM или AES-CCM.Добавьте дополнительное поле id на шаге 1. Добавьте ip на игровой сервер.

Шаг 4: Упакованные данные + ключ шифрования сеанса RC4 + IP-адрес на игровой сервер отправляются какответить.

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

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

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

Шаг 6: Игровой сервер распаковывает данные, упакованные в (3).Теперь он знает пользователя и ключ шифрования RC4, который должен использовать.

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

Шаг 8: Если все в порядке, сервер отправляет незашифрованный LOGIN_OK, и начинается зашифрованная связь RC4.

В этот момент игровой сервер не может быть уверен вличность клиента.Используйте ключ сеанса и зашифруйте одноразовый номер + строго увеличивающийся идентификатор сеанса + состояние успешного входа в систему с помощью AES-GCM / CCM и отправьте его клиенту.

Клиент расшифровывает и проверяет состояние успешного входа в систему.Если это так, то клиент знает, что игровой сервер знает ключ сеанса (GCM / CCM проверяет, что пакет не был подделан).Клиент возвращает sid + nonce.

Сервер проверяет, что sid + nonce совпадает с отправленными значениями.

Наконец, клиент и сервер создают новые ключи сеанса, хешируя ключ сеанса с помощьюsid + nonce + salt для создания ключа для последующей связи, чтобы предотвратить возможную атаку воспроизведения.

Относительно RC4

В RC4 есть уязвимости, но, вероятно,было бы достаточно для этой схемы из-за довольно агрессивной перепланировки ключей.Однако существуют современные шифры, которые более безопасны и быстрее, такие как Snow 2.0 или Trivium.

1 голос
/ 17 февраля 2011

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

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

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

0 голосов
/ 17 февраля 2011

Просто используйте SSL к игровому серверу. Современный криптоанализ привел к нескольким очень быстрым реализациям некоторых из лучших алгоритмов шифрования. Например, хорошо оптимизированные реализации AES могут легко зашифровывать со скоростью более 150 МБ / с на любой удаленно современной машине. Кроме того, хотя AES пользуется большим уважением, у него есть две слабости, о которых я знаю, но при правильном использовании эти недостатки становятся незначительными.

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

...