Создание криптографически безопасных токенов аутентификации - PullRequest
56 голосов
/ 08 мая 2009

Справочная информация:

Это действительно общий вопрос передового опыта, но некоторые сведения о конкретной ситуации могут быть полезны:

Мы разрабатываем «подключенное» приложение для iPhone. Он будет связываться с серверным приложением через службы REST. Чтобы не запрашивать у пользователя имя пользователя и пароль при каждом запуске приложения, мы предоставим сервис «Логин», который проверяет их имя пользователя и пароль при первом запуске и возвращает токен аутентификации, который может быть использован для будущего Интернета. запросы на обслуживание для реальных данных. Срок действия токена может истечь, после чего мы попросим его повторно пройти аутентификацию с использованием своего имени пользователя / пароля.

Вопрос:

Каковы рекомендации по созданию токена такого типа для аутентификации?

Например, мы могли бы ...

  • Хеширует (SHA-256 и т. Д.) Случайную строку и сохраняет ее в базе данных для данного пользователя вместе с датой истечения срока действия. Выполните простой поиск токена при последующих запросах, чтобы убедиться, что он совпадает.
  • Зашифруйте идентификатор пользователя и некоторую дополнительную информацию (временную метку и т. Д.) С помощью секретного ключа. Расшифруйте токен при последующих запросах, чтобы убедиться, что он выдан нами.

Такое ощущение, что это должна быть решенная проблема.

Ответы [ 7 ]

29 голосов
/ 13 мая 2009

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

Довольно быстро было отмечено, что модель взаимодействия здесь по существу точно такая же, как и модель, используемая для проверки подлинности с помощью форм в ASP.NET, когда установлен флажок «запомнить меня». Это просто не веб-браузер, делающий HTTP-запросы. Наш «билет» эквивалентен cookie-файлу, который устанавливает Аутентификация с помощью форм. Аутентификация с помощью форм по умолчанию использует подход «шифровать некоторые данные с помощью секретного ключа» по умолчанию.

В нашем веб-сервисе для входа в систему мы используем этот код для создания заявки:

string[] userData = new string[4];

// fill the userData array with the information we need for subsequent requests
userData[0] = ...; // data we need
userData[1] = ...; // other data, etc

// create a Forms Auth ticket with the username and the user data. 
FormsAuthenticationTicket formsTicket = new FormsAuthenticationTicket(
    1,
    username,
    DateTime.Now,
    DateTime.Now.AddMinutes(DefaultTimeout),
    true,
    string.Join(UserDataDelimiter, userData)
    );

// encrypt the ticket
string encryptedTicket = FormsAuthentication.Encrypt(formsTicket);

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

// get the Forms Auth ticket object back from the encrypted Ticket
FormsAuthenticationTicket formsTicket = FormsAuthentication.Decrypt(encryptedTicket);

// split the user data back apart
string[] userData = formsTicket.UserData.Split(new string[] { UserDataDelimiter }, StringSplitOptions.None);

// verify that the username in the ticket matches the username that was sent with the request
if (formsTicket.Name == expectedUsername)
{
    // ticket is valid
    ...
}
13 голосов
/ 08 мая 2009

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

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

http://web.mit.edu/kerberos/dialogue.html

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

http://web.mit.edu/kerberos/www/advisories/MITKRB5-SA-2003-004-krb4.txt

Намного лучше учиться на их ошибках, чем на собственных.

11 голосов
/ 09 мая 2009

Amazon.com использует токен сообщения SHA-1 HMAC для аутентификации и авторизации запросов. Они используют это для довольно крупного коммерческого сервиса, поэтому я буду склонен доверять их инженерным решениям. Google публикует OpenSocial API , что несколько похоже. Основываясь на том, что Google и Amazon.com используют похожие и открыто опубликованные подходы к защите веб-запросов, я подозреваю, что это, вероятно, хорошие пути.

3 голосов
/ 13 мая 2009

Любой из двух предоставленных вами ответов будет достаточным. Вы можете найти рамки, которые делают это для вас, но правда в том, что это не так сложно построить. (Каждая компания, в которой я работал, создала свою собственную.) Выбор сохраненных в базе данных токенов в сравнении с зашифрованными данными «куки» - архитектурное решение - хотите ли вы просматривать базу данных при каждом просмотре страницы, или вы предпочитаете жевать процессор с дешифровкой cookie? В большинстве приложений использование зашифрованных файлов cookie обеспечивает выигрыш в производительности в масштабе (если это важно). В противном случае это просто вопрос вкуса.

1 голос
/ 28 июля 2014

Вы должны реализовать:

  1. OAuth2 Implicit Grant - для сторонних приложений http://tools.ietf.org/html/rfc6749#section-1.3.2
  2. Учетные данные пароля владельца ресурса OAuth2 - для вашего мобильного приложения http://tools.ietf.org/html/rfc6749#section-1.3.3

- это именно те рабочие процессы из OAuth2, которые вы ищете. Не изобретайте велосипед.

1 голос
/ 10 мая 2009

Поскольку вы используете WCF, у вас есть множество вариантов при использовании CFNetwork - например, NTLM или дайджест-аутентификация:

http://developer.apple.com/documentation/Networking/Conceptual/CFNetwork/Concepts/Concepts.html#//apple_ref/doc/uid/TP30001132-CH4-SW7

Я знаю, что это не отвечает на ваш конкретный вопрос, но я также столкнулся с этой проблемой (iPhone - Tomcat) и решил максимально использовать службы аутентификации на веб-сервере. В большинстве случаев нет существенных штрафов за включение информации об аутентификации в каждый запрос. Быстрый Google находит много постов в блоге о WCF и сервисах RESTful (и некоторые связанные вопросы о StackOverflow).

Надеюсь, это поможет!

0 голосов
/ 08 мая 2009

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

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

Безопасность зависит от непредсказуемости идентификаторов сеанса. Создайте их с помощью криптографического RNG из очень большого пространства.

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