Я реализую веб-службу REST с использованием С#, которая будет размещаться на Azure в качестве облачного сервиса. Поскольку это служба REST, она не имеет состояния и, следовательно, не содержит cookie или сеанса.
Доступ к веб-сервису возможен только через HTTPS (сертификат, предоставляемый StartSSL.com).
После успешного входа пользователя в службу они получат маркер безопасности. Этот токен обеспечит аутентификацию в будущих сообщениях.
Токен будет содержать отметку времени, идентификатор пользователя и IP-адрес клиента.
Все общение будет происходить только через HTTPS, поэтому меня не волнует, что токен перехватывается и используется при повторных атаках; в любом случае токен будет истекать.
Поскольку это служба, обращенная к публике, я, однако, обеспокоен тем, что кто-то может зарегистрироваться в сервисе, войти в систему и затем модифицировать токен, который они получают для доступа к учетным записям других пользователей.
Мне интересно, как лучше всего защитить содержимое токена, а также проверить, что он не был изменен.
Я планирую сделать следующее, чтобы защитить токен:
Клиент успешно выполняет вход в службу, и служба выполняет:
- Создайте случайное значение и хэш его с SHA256 1000 раз.
- Генерировать одноразовый ключ сеанса из личного ключа + хешированное случайное значение.
- Хешируйте сеансовый ключ с SHA256 1000 раз, а затем используйте его для шифрования токена
- Используйте закрытый ключ для подписывания зашифрованного токена с помощью RSA.
- Отправляет зашифрованный токен + подпись + хешированное случайное значение клиенту в незашифрованном пакете JSON.
Когда клиент вызывает службу, он отправляет зашифрованный токен и подпись в незашифрованном пакете JSON для этой службы. Служба будет
- Восстановить ключ сеанса из закрытого ключа + хешированное случайное значение
- Используйте закрытый ключ для проверки подписи
- Используйте хешированный ключ сеанса для дешифрования токена
- Убедитесь, что токен не истек.
- Продолжить запрошенную операцию...
Я ничего не знаю о шифровании, поэтому у меня есть несколько вопросов:
- Достаточно ли это или это слишком много?
- Я прочитал, что для обнаружения фальсификации я должен включить HMAC с токеном. Поскольку я подписываюсь с закрытым ключом, мне все еще нужен HMAC?
- Должен ли я использовать Rijndael вместо RSA?
- Если Rijndael является предпочтительным, генерируется ли IV для дешифрования? то есть я могу выбросить его или мне нужно отправить его зашифрованный токен? например Шифрованный токен + HMAC + IV + хешировал случайное значение.
Поскольку всякое общение происходит через HTTPS, незашифрованный пакет JSON на самом деле не зашифрован до тех пор, пока он не достигнет клиента.
Также я могу захотеть повторно реализовать службу в PHP позже, поэтому все это должно быть выполнимо и в PHP.
Спасибо за помощь