Обмен криптографическими ключами между клиентом и сервером
Я видел много примеров проверки клиентских или серверных сертификатов с использованием API-интерфейсов инфраструктуры безопасности, но это решит только проблему Identification
функций безопасности, но как насчет Confidentiality
данных? Как я могу обмениваться закрытыми и открытыми ключами между клиентом и сервером? Как насчет Interception
, Modifications
, или же Fabrication
атаки? Что делать, если кто-то притворяется и отправляет правильный сертификат, как ожидал клиент?
1 ответ
Идентификация обеспечивается путем проверки сертификата, как вы отмечаете. Конфиденциальность обеспечивается с помощью шифрования. Аутентификация обеспечивается подписью данных. Вместе они часто реализуются через TLS через сетевое соединение.
Короче говоря, если вы правильно внедрите и развернете HTTPS и подтвердите свои сертификаты, то вы получите все, что вы описываете. NSURLConnection
сделает почти все это по умолчанию, если вы просто используете URL-адрес "https".
Если вы развернете сертификат на сервере и защитите его закрытый ключ, то злоумышленник не сможет претендовать на получение этого сертификата. Только у сервера есть закрытый ключ сервера (от вас зависит защита закрытого ключа от копирования или кражи).
Типичный подход заключается в использовании коммерческого сертификата, в котором центр сертификации (CA), такой как Verisign, подтверждает, что закрытый ключ был выдан владельцу данного хоста (известного как CN или общее имя). Это простой в использовании подход, который в целом экономически эффективен. Пойдите в один из известных CA и купите свидетельство.
Однако вы также можете создать свою собственную пару ключей открытого / частного сервера, защитить закрытый ключ и распространить открытый ключ в своем клиенте. Затем вы можете настроить свой клиент так, чтобы он принимал только один сертификат, а не другие. Это на самом деле более безопасно, чем коммерческий сертификат. Пример этого см. В SelfCert. Это из моего выступления на CocoaConf-RTP-2012. Я буду выступать с аналогичным докладом на CocoaConf-DC-2013. Это также подробно обсуждается в главе 15 iOS: PTL.
Клиентские сертификаты встречаются реже. Они используются для аутентификации клиента, а не сервера. Для правильной работы сертификата клиента каждый клиент должен иметь свой собственный сертификат. Вы не можете отправить закрытый ключ как часть вашего пакета. Если вы это сделаете, любой может использовать этот закрытый ключ для олицетворения клиента. (И наоборот, совершенно нормально поместить открытый ключ сервера в пакет. Он публичный; вам все равно, кто его увидит.)
С CFNetwork
после подключения вам нужно будет использовать CFReadStreamCopyProperty
чтобы получить kCFStreamPropertySSLPeerTrust
, Затем вы можете оценить возвращенный SecTrust
объект. Тем не менее, я рекомендую NSURLConnection
код, если вы можете использовать его. Если вам нужен доступ более низкого уровня, вы все равно можете использовать NSStream
, Джефф Ламарш обсуждает это в NSStream: TCP и SSL. Но я бы порекомендовал такой инструмент, как AFNetworking или CocoaAsyncSocket, если вам нужен более низкий уровень контроля над TCP+SSL.