Иногда бывает любопытно подсмотреть, что пересылают туда-сюда разные Android-приложения по HTTP и HTTPS протоколам. Иногда даже при разработке собственного ПО удобно видеть весь трафик в реальном времени. Для реализации этих задач давно придумано много хороших программ, таких, к примеру, как Charles или Fiddler2. На самом деле их намного больше, вот только две вышеуказанные дают возможность нормально просматривать не только HTTP, но и HTTPS.
Трудности начинаются тогда, когда речь заходит о перехвате трафика между Андроид-устройством и внешним сервером. В случае незашифрованного (HTTP-протокол) трафика всё весьма тривиально (вот и инструкция есть) — разрешаем Fiddler2 внешние соединения, в Андроиде устанавливаем прокси сервером адрес нашей машины с Fiddler2 — и вуаля, всё работает. А вот на настройку перехвата HTTPS-трафика у меня ушло чуть больше времени.
Теория
Итак, в чём же сложность? В том, что при использовании протокола HTTPS клиент по-умолчанию проверяет, а действительно ли тот сервер, к которому он подключился, является нужным. Для этого используются сертификаты. И вот у настоящего сервера этот сертификат, понятное дело, тоже настоящий и соответствует открытому URL, а вот у нашего прокси — нет. Для решения этой проблемы в десктопных операционных системах в таких случаях есть возможность сгенирировать в Fiddler2 поддельный сертификат, импортировать его в доверенные — и теперь клиент всегда будет верить, что соединение с Fiddler2 вполне безопасно. К сожалению, с мобильным устройством такой легкий финт ушами не прошел.
Во-первых, возможности импортировать внешний сертификат в Андроиде версий младше 4.0 нет. Есть какие-то не внушающие доверия варианты с рутоваными девайсами — но это не наш путь.
Во-вторых, в Андроид даже версии 4.0 импортировать сертификат Fiddler2 не получается. Дело в том, что генерируемый по-умолчанию сертификат не соответствует каким-то там Андроидовским критериям безопасности и не устанавливается. Его нужно генерировать специальным образом.
В-третьих, совсем даже не факт, что все подряд программы сразу поверят поддельному сертификату. Есть нюансы.
Практика
- Берём устройство с Андроидом версии 4.0 или выше. Нет, девайс с 2.3 не подойдет. Да, эмулятор версии 4.0 подойдет.
- Устанавливаем на компьютер последнюю версию Fiddler2.
- Устанавливаем специальные библиотеки генерации Андроид-совместимого сертификата безопасности отсюда.
- Экспортируем из Fiddler2 сертификат безопасности («Tools->Fiddler Options->HTTPS->Export root certificate to Desktop»). Кладём на флешку, в корень (ну или на эмулятор, если вы используете его).
- На Андроиде добавляем сертификат безопасности в доверенные(«Settings > Security > Install from SD card»)
- Запускаем Fiddler2, разрешаем в настройках внешние коннекты
. - На Андроиде в настройках сети прописываем в качестве прокси адрес нашей десктопной машины с Fiddler2.
- На Андроиде открываем браузер, вводим google.com — и видим запрос с ответом в окне Fiddler2.
Итак, с браузером получилось. К сожалению, не все программы столь доверчивы, как браузер. К примеру, в моей собственной софтине, где я использую Apache HTTP Client, способ не прокатил — плевал апачевский клиент на доверенные сертификаты операционки. В этом случае мне пришлось отключить эту проверку вручную, таким вот образом:
Protocol.registerProtocol("https", new Protocol("https", new EasySSLProtocolSocketFactory(), 443));
где EasySSLProtocolSocketFactory взят отсюда и разрешает доверие к любым сертификатам.
Не безопасно, только для отладки!
После этого трафик моей программы стал также успешно отображаться в Fiddler2.
Автор: tangro