Аутентификация SSL с сертификатами: должны ли сертификаты иметь имя хоста? - PullRequest
6 голосов
/ 08 апреля 2010

Быстрая версия вопроса

Gmail, TD (канадский банк), Royal Bank (канадский банк) - все используют ssl. Когда вы проверяете их сертификаты, все они имеют

Common Name (CN)   mail.google.com

Или, в более общем смысле:

Common Name (CN)   <url>

Нужно ли это, чтобы предотвратить атаки человека в середине?

Резюме

JBoss позволяет клиентам и серверам проходить аутентификацию с использованием сертификатов и ssl. Одна вещь, которая кажется странной, заключается в том, что вы не обязаны указывать имя вашего хоста в сертификате.

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

(И точно так же: если Клиент B находится в вашем доверенном хранилище ...)

Я что-то здесь упускаю?

Аутентификация Шаги

( Сводка страницы Википедии )

Client                                                  Server
=================================================================================================
1) Client sends Client Hello
        ENCRIPTION: None
        - highest TLS protocol supported
        - random number
        - list of cipher suites
        - compression methods

                                                        2) Sever Hello
                                                                ENCRIPTION: None
                                                                - highest TLS protocol supported
                                                                - random number
                                                                - choosen cipher suite
                                                                - choosen compression method

                                                        3) Certificate Message
                                                                ENCRIPTION: None
                                                                -

                                                        4) ServerHelloDone
                                                                ENCRIPTION: None

5) Certificate Message
        ENCRIPTION: None

6) ClientKeyExchange Message
        ENCRIPTION: server's public key => only server can read
                => if sever can read this he must own the certificate
        - may contain a PreMasterSecerate, public key or nothing (depends on cipher)

7) CertificateVerify Message
        ENCRIPTION: clients private key
        - purpose is to prove to the server that client owns the cert


                        8) BOTH CLIENT AND SERVER:
                                - use random numbers and PreMasterSecret to compute a common secerate


9) Finished message
        - contains a has and MAC over previous handshakes
                (to ensure that those unincripted messages did not get broken)


                                                        10) Finished message
                                                                - samething

Север знает

  • У клиента есть открытый ключ для отправленного сертификата (шаг 7)

  • Сертификат клиента действителен потому что:

    • подписано ЦС (verisign)
    • Самозаверяющий, НО в хранилище доверенных сертификатов на сервере
  • Это не повторная атака, поскольку предположительно случайное число (шаг 1 или 2) отправляется с каждым сообщением

Клиент знает

  • На сервере есть открытый ключ для отправленного сертификата (шаг 6 с шагом 8)

  • Сертификат сервера действителен потому что либо:

    • подписано ЦС (verisign)
    • он был самоподписан, НО он находится в доверенном хранилище клиента
  • Это не повторная атака, потому что предположительно случайное число (шаг 1 или 2) отправляется с каждым сообщением

Потенциальная проблема

  • Предположим, что в доверенном хранилище клиента есть сертификаты:

    • Сервер A
    • Сервер B (яблочный)
  • Сервер A имеет имя хоста www.A.com

  • Сервер B имеет имя хоста www.B.com

  • Предположим: клиент пытается подключиться к серверу A, но сервер B запускает человека в середине атаки.

  • С сервера B:

    • имеет открытый ключ для сертификата, который будет отправлен клиенту
    • имеет «действительный сертификат» (сертификат в доверенном хранилище)
  • А так как:
    • сертификаты не содержат имени хоста

Кажется, что Сервер B может легко выдавать себя за Сервер А.

Есть что-то, чего мне не хватает?

Ответы [ 2 ]

2 голосов
/ 13 апреля 2010

Я думаю, что вы что-то упустили, но я не уверен, что понимаю ваши рассуждения.

Однако, когда сервер B пытается запустить человека в середине атаки, вы говорите, что у него есть открытый ключ. Это правда, но для настройки ssl-соединения у вас также должен быть закрытый ключ, принадлежащий этому открытому ключу. Кроме того, используемый сертификат связан с именем DNS (в случае https). Таким образом, клиент пытается подключиться к A, он вводит www.a.com. Поскольку мы предполагаем, что B не знает секретный ключ A, у него будет другая пара ключей. Он никогда не мог получить действительный (то есть доверенный) сертификат от основного ЦС, который связан с доменом, который ему не принадлежит.

Поэтому B никогда не мог получить сертификат с общим именем www.A.com, по этой причине B не мог выполнить человека в средней атаке.

2 голосов
/ 09 апреля 2010

Можете ли вы указать на какой-нибудь текст, который говорит, что JBoss не нуждается в имени хоста в сертификате, или это просто ваше наблюдение? Я предполагаю, что под именем хоста вы подразумеваете общее имя (CN) или отличительное имя (DN) ??

Обычно приложение должно проверить сертификат X.509 для:

Допустимый диапазон дат
Использование (например, аутентификация сервера)
Цепочки к доверенному корню
CN == DNS-имя целевого хоста (это может быть другое имя, а не только DNS)
Не аннулирован (с использованием CRL или OCSP)

Технически, приложение может игнорировать любой из них и просто указывать, что с сертификатом все в порядке .... но это плохо :)

...