Защита клиента javascript с помощью hmac
Я исследую способы защиты приложения javascript, над которым я работаю. Приложение является клиентом чата, который использует APE (Ajax Push Engine) в качестве бэкэнда.
В настоящее время любой может получить доступ к странице и сделать запрос GET/POST к серверу APE. Я хочу обслуживать клиент чата только зарегистрированным пользователям и хочу, чтобы только их запросы были приняты. Я могу использовать аутентификацию по имени пользователя / паролю с PHP, чтобы обслуживать пользователя на странице. Но как только они получат страницу, что может помешать им изменить javascript или позволить ему попасть в чужие руки?
Этот метод защиты клиент-серверного приложения выглядит многообещающе: http://abhinavsingh.com/blog/2009/12/how-to-add-content-verification-using-hmac-in-php/
У меня есть другой источник, который говорит, что это идеально подходит для клиента JavaScript, так как это не зависит от отправки закрытого ключа. Но как это может быть? В соответствии с приведенным выше руководством клиент должен предоставить закрытый ключ. Это кажется не очень безопасным, поскольку у любого, у кого есть JavaScript, теперь есть закрытый ключ этого пользователя. Из того, что я понимаю, будет работать что-то вроде этого:
- Пользователь входит в систему с именем пользователя и паролем
- PHP проверяет имя пользователя и пароль, ищет закрытый ключ пользователя и вставляет его в JavaScript
- Javascript предоставляет подпись (используя закрытый ключ) и открытый ключ со всеми запросами APE
- APE сравнивает вычисленную подпись с полученной подписью и решает, обрабатывать ли запросы.
Насколько это безопасно, если приложение javascript должно знать о секретном ключе?
Спасибо за помощь!
3 ответа
Аутентификация HMAC лучше подходит для API, к которому будут подключаться третьи стороны. Похоже, что ваше приложение будет лучше обслуживаться, если в браузер клиента будет добавлен файл cookie, указывающий, что они были аутентифицированы. Затем с каждым ajax-запросом вы можете проверить этот cookie.
Изменить: Я забираю немного из того, что я сказал о HMAC лучше обслуживать сторонних API. Традиционно с HMAC каждый пользователь получает свой собственный закрытый ключ. Я не думаю, что это необходимо для вашего приложения. Возможно, вам не удастся просто сохранить один главный закрытый ключ и дать каждому пользователю уникальный "открытый" ключ (я называю его открытым ключом, но на самом деле пользователь никогда не узнает о ключе). Когда пользователь входит в систему, я бы написал два куки. Тот, который представляет собой комбинацию открытого ключа пользователя + зашифрованной метки времени, и другой ключ, указывающий, что такое метка времени. Затем на стороне сервера вы можете проверить зашифрованный ключ и проверить, что отметка времени находится в пределах заданного порога (скажем, 10-30 минут, если они бездействуют в вашем приложении). Если они проверены, обновите зашифрованный ключ и отметку времени, промойте и повторите.
Ответ: технически вы не можете запретить пользователю изменять JavaScript. Так что не беспокойтесь об этом, потому что вы ничего не можете с этим поделать.
Тем не менее, атака, которую вам нужно предотвратить, это подделка межсайтовых запросов (CSRF). Вредоносные сценарии в разных доменах могут автоматически отправлять формы на ваш домен с помощью файлов cookie, сохраняемых браузером. Чтобы справиться с этим, вам нужно включить токен аутентификации (который должен быть достаточно случайным, не связанным с именем пользователя или паролем и отправленным на HTML-странице, на которой находится клиент чата) в фактические данные, отправленные запросом AJAX (который не заполняется автоматически браузером).
Насколько это безопасно, если приложение javascript должно знать о секретном ключе?
Почему бы и нет? Это собственный закрытый ключ пользователя, поэтому, если он хочет передать его кому-то другому, это его проблема. Это не отличается от того, что вы даете свой пароль и затем говорите, что кто-то другой имеет доступ к вашей учетной записи.
Если вы немного подумаете об этом, вы поймете, что вам не нужно реализовывать шифрование с открытым ключом, HMAC или что-то подобное. Ваша обычная сеансовая аутентификация подойдет, если сам канал связи безопасен (скажем, с использованием HTTPS).