Как правильно сформировать запрос, чтобы данные передавались зашифрованными и какие части запроса шифруются
Что проверяют
Понимаете ли вы, что именно защищает TLS, и отличаете ли его от дополнительных мер вроде пиннинга и шифрования тела. Следом обычно спрашивают, видны ли кому-то query-параметры и как защититься от перехвата через установленный пользователем корневой сертификат.
Как отвечать
- HTTPS по умолчанию:
URLSessionс адресомhttps://. App Transport Security блокирует обычный HTTP и требует TLS 1.2 и выше с forward secrecy. Исключения вInfo.plist(NSAllowsArbitraryLoads,NSExceptionDomains) ослабляют защиту, их включают точечно и осознанно; - что шифруется: внутри TLS идёт всё HTTP-сообщение: метод, путь, query-строка, заголовки вместе с
Authorizationи cookie, тело; - что остаётся видно: IP-адрес и порт сервера, DNS-запрос, если не используется зашифрованный DNS, имя хоста в SNI при установке соединения (Encrypted Client Hello пока поддерживается далеко не везде), объём и тайминги трафика.
Отсюда практическое правило: токены и персональные данные передают в заголовках и теле, а не в URL. Query зашифрован в канале, но оседает в логах сервера, прокси и аналитики.
Дальше по модели угроз:
- пиннинг: против MITM с подменным корневым сертификатом. Декларативно через
NSPinnedDomainsвInfo.plist(iOS 14+) или вurlSession(_:didReceive:completionHandler:), где сверяют хэш публичного ключа. Держите запасной пин, иначе плановая смена сертификата отрежет приложение от сервера; - шифрование тела:
CryptoKit, напримерAES.GCM.seal, поверх TLS, когда данные должны оставаться закрытыми и после терминации TLS на балансировщике. Ключ согласуют с сервером, например черезCurve25519.KeyAgreement, и хранят в Keychain, а не в коде.
Где спотыкаются
Говорят, что HTTPS скрывает всё, включая адрес сайта. Имя хоста видно в SNI и DNS, скрыты только путь и всё, что после него.
Кладут токен в query-параметр с мыслью «всё равно же зашифровано». В канале он действительно закрыт, а в логах и истории лежит открытым текстом.
Предлагают собственное AES-шифрование с ключом, зашитым в приложение, как замену TLS. Ключ достаётся из бинарника, и защита оказывается видимостью.