Проверка подписи Android SafetyNet JWT

Я пытаюсь понять, как работает проверка подписи JWT.

Вот как я это делаю на данный момент:

1) My app calls the attest api
2) My app sends the jwt to my server
3) My server verify the signature (third field of the jwt) using the certificate provided in the header of the jwt.

Я понимаю, что подпись создается путем хеширования заголовка и полезной нагрузки jwt, а затем подписания (шифрования) с помощью закрытого ключа Google.

На третьем этапе я беру заголовок + полезную нагрузку, дешифрую его с помощью открытого ключа сертификата и проверяю, совпадает ли он с подписью. (когда я говорю "я", я имею в виду, что это делает библиотека)

Моя проблема в том, что произойдет, если на пользовательском устройстве появится вредоносная программа и на лету исправит JWT, отправляемый на мой сервер? Вредоносная программа добавит в заголовок свой собственный сертификат (выданный доверенным центром сертификации), изменит полезную нагрузку и создаст подпись.

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

Это правильно? Или я где-то запутался? Потому что в этом случае это сделало бы весь этот поток немного бесполезным, нет? Как можно на 100% застраховать себя, что JWT исходит от Google?

2 ответа

Ключевым моментом является проверка того, что сертификат подписи выдан attest.android.com доверенным центром сертификации

Любой доверенный центр сертификации выдаст поддельный сертификат attest.android.com, Посмотрите, что произойдет, если они примут участие в плохой практике https://security.googleblog.com/2016/10/distrusting-wosign-and-startcom.html?m=1

Посмотреть документ Google

Проверьте ответ проверки совместимости

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

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

Выполните следующие действия, чтобы проверить источник сообщения JWS:

  1. Извлеките цепочку сертификатов SSL из сообщения JWS.

  2. Проверьте цепочку сертификатов SSL и используйте сопоставление имени хоста SSL, чтобы убедиться, что конечный сертификат был выдан имени хоста atst.android.com.

  3. Используйте сертификат для проверки подписи сообщения JWS.

  4. Проверьте данные сообщения JWS, чтобы убедиться, что оно совпадает с данными вашего исходного запроса. В частности, убедитесь, что nonce, timestamp, имя пакета и SHA-256 совпадают.

Вторая точка требует проверки цепочки сертификатов. Предполагается, что используется диспетчер доверия, содержащий корневой сертификат центра сертификации.

Я проверил образец кода Google в OfflineVerify, чтобы убедиться в существовании TrustManager, поскольку он прямо не указан и эффективно используется во время проверки JWS. Он использует систему по умолчанию TrustManager, но вы можете использовать пользовательский

Обратите внимание, что используется JWS (Json Web Signature), а не JWT. JWT - это обычно токен аутентификации, подписанный с помощью JWS.

Вы правильно поняли концепцию. Однако то, что вы упустили из виду, это то, что используемая вами библиотека, вероятно, проверяет, является ли сертификат, из которого извлекаются открытые ключи, действительным и "доверенным" сертификатом (AKA исходит от доверенного CA)

Благодаря этому (и, как указано в документе), вам необходимо убедиться, что сертификат был выдан "contest.android.com". Никто не сможет подделать сертификат, чтобы он пришел из этого ЦС, потому что.

Это то, что я понял по крайней мере, поправьте меня, если я ошибаюсь.

Другие вопросы по тегам