Использование HTTPS с Monotouch и WCF

у нас есть приложение, работающее с монотач на iPhone. На данный момент мы используем BasicHttpBinding для подключения к службе WCF. Теперь мы делаем соединение безопасным, снова используя BasicHttpBinding с BasicHttpSecurityMode.Transport (фактически это HTTPS).

Мы создали самоподписанный сертификат и добавили его на сервер. При доступе к серверу-адресу через браузер (как с iPhone, так и с ПК) мы можем подключиться к нему без проблем. Однако, если мы подключимся к нашему приложению MonoTouch, мы получим следующее исключение:

    System.Net.WebException has been thrown
    Error writing request: BeginWrite failure

Мы использовали Wireshark для анализа соединения и обнаружили, что сервер закрывает соединение (сервер отправляет tcp reset после получения ClientHello). Мы нашли в журнале ошибок IIS следующее сообщение:

    An TLS 1.0 connection request was received from a remote client application, but none of the cipher suites supported by the client application are supported by the server. The SSL connection request has failed.

Если мы посмотрим, какие шифры поддерживает наш сервер, мы увидим следующий список:

    TLS_RSA_WITH_AES_128_CBC_SHA256
    TLS_RSA_WITH_AES_128_CBC_SHA
    TLS_RSA_WITH_AES_256_CBC_SHA256
    TLS_RSA_WITH_AES_256_CBC_SHA
    TLS_RSA_WITH_RC4_128_SHA
    TLS_RSA_WITH_3DES_EDE_CBC_SHA
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P384
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P256
    TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA_P384
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P256
    TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384
    TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256_P256
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256_P256
    TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384_P384
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384_P384
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P256
    TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA_P384
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P256
    TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA_P384
    TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
    TLS_DHE_DSS_WITH_AES_128_CBC_SHA
    TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
    TLS_DHE_DSS_WITH_AES_256_CBC_SHA
    TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
    TLS_RSA_WITH_RC4_128_MD5
    SSL_CK_RC4_128_WITH_MD5
    SSL_CK_DES_192_EDE3_CBC_WITH_MD5
    TLS_RSA_WITH_NULL_SHA256
    TLS_RSA_WITH_NULL_SHA

Принимая во внимание, что мы знаем, что Monotouch по крайней мере поддерживает TLS_RSA_WITH_AES_128_CBC_SHA (согласно Wireshark)

Есть ли у кого-нибудь решение этой проблемы или обходной путь? Может быть, нам нужно использовать какие-то специальные опции в IIS или в makecert?

Заранее спасибо!


person Kroan    schedule 09.05.2012    source источник


Ответы (2)


Ваш браузер отображает ошибку сертификата? Если это так, вы должны использовать:

ServicePointManager.ServerCertificateValidationCallback = (a, b, c, d) => true;

Сделайте это один раз в своей программе перед вашим первым запросом. Он автоматически принимает все сертификаты, даже самоподписанные.

Тем не менее, я думаю, что MonoTouch должен выдавать здесь другое сообщение об ошибке. Что происходит в Windows?

person jonathanpeppers    schedule 09.05.2012

Mono (и MonoTouch) поддерживают многие шифры из вашего списка (большинство, кроме *DH*).

Ошибка в вашем журнале предполагает, что сервер не принимает соединение из-за выбора шифра. В SSL/TLS клиент отправляет свой список на сервер, и сервер выбирает тот, который он предпочитает (производительность/безопасность). На стороне Mono[Touch] вы ничего не можете изменить, чтобы повлиять на это.

Я видел такие случаи только, когда сервер не настроен на прием любого из предложенных шифров (от Mono). Как правило, серверы настроены на поддержку только шифров *DH*.

Не всегда легко быть на 100 % уверенным в том, что сервер поддерживает (или разрешает). Протокол SSL/TLS никогда не отправляет такой список (в отличие от клиента).

Я предлагаю вам использовать Wireshark и некоторые веб-браузеры для подключения к серверу. Если соединение работает и используется шифр *DH*, то вы будете знать (98%), что ваш сервер, вероятно, неправильно настроен (согласно приведенному выше списку).

Почему ? потому что браузеры обычно поддерживают множество шифров (например, Mono) и *DH* (в отличие от Mono). Таким образом, если сервер выбрал шифр *DH*, это хороший признак того, что он не допускает ничего другого. Обычный выбор для серверов имеет тенденцию использовать RC4 или AES, но YMMV.

person poupou    schedule 10.05.2012