Тема Java MTLS и заказ эмитента

Мы обновляем соединение между собой и партнером, они требуют, чтобы мы обновились до MTLS. Я отлаживал низкоуровневую java,

javax.net.debug=allи я вижу, что рукопожатие прошло успешно. Однако партнер сопоставляет полную строку с полями "Тема" и "Издатель" и сравнивает с полями something в своей базе данных.

Я использовал следующее,

   if (cert instanceof X509Certificate) {
        X509Certificate x509cert = (X509Certificate) cert;

        // Get subject
        Principal principal = x509cert.getSubjectDN();
        String subjectDn = principal.getName();
        logger.error(subjectDn);
        // Get issuer
        principal = x509cert.getIssuerDN();
        String issuerDn = principal.getName();
        logger.error(issuerDn);
    }

чтобы сбросить значения, которые имеет java. Интересное примечание: openssl сообщает о них в совершенно ином порядке, чем отчеты java.

Я сейчас копался в Wireshark и вижу рукопожатие с этого уровня, однако, похоже, он переводит имена на id-at-commonName, pkcs-9-at-emailAddress насколько я могу судить.

Есть ли способ узнать, что на самом деле отправляется?

1 ответ

Решение

Нет протокола MTLS, но похоже, что вас интересует аутентификация клиента, также называемая взаимной аутентификацией, в TLS, который, как и аутентификация сервера, обычно использует сертификаты типа X.509 (точнее, PKIX).

Предпосылки: сертификаты X.509/PKIX идентифицируют Субъекта и Эмитента (а иногда и другие объекты / объекты в некоторых расширениях) с помощью структуры отличительного имени X.500/501, также называемой X500Name, X501Name или просто Name. Эта структура определена в ASN.1 как ПОСЛЕДОВАТЕЛЬНОСТЬ (упорядоченная) элементов RelativeDistinguishedName, каждый из которых официально представляет собой НАБОР (неупорядоченный) пар (ПОСЛЕДОВАТЕЛЬНОСТЬ) типа и значения атрибута, хотя на практике НАБОРЫ RDN почти всегда являются одиночными, так что имя фактически представляет собой последовательность типа и значения атрибута. Этот формат имени был разработан для использования в глобальной распределенной иерархической сети "каталогов", скорее как DNS. за исключением (поскольку CCITT-now-ITU-T - это организация правительственных агентств) в основном базирующихся на национальных каталогах стран, а не в функциональных или "общих", таких как .com .org .edu .gov .mil .net, а сертификаты X.509 были разработаны как экспорт данных из этой сети каталогов, которые можно использовать в автономном режиме. На практике настоящие каталоги X.500 вообще не используются, и даже протоколы для них, такие как LDAP (Lightweight Directory Access Protocol), используются нечасто, за исключением доменов Microsoft Windows (Active Directory), но сертификатов X.509 включая используемый в них формат имени, широко используются в SSL-now-TLS, S/MIME и многих других приложениях.

Традиционная текстовая или внешняя форма DN представляет собой серию элементов attr=value, где attr обычно сокращается, например C для страны, ST для StateOrProvince, CN для CommonName и т. Д. Java использует определенную стандартизованную форму (с небольшими изменениями / улучшения) RFC 1485, 1779, 2253 и 4514, где элементы разделены запятыми и приведены в обратном порядке, то есть от последнего (самый низкий уровень) к первому (самый высокий уровень обычно корневой), аналогично DNS. Например, Java отображает тему сертификата, используемого в настоящее время www.duckduckgo.com как

CN=*.duckduckgo.com, O="Duck Duck Go, Inc.", L=Paoli, ST=Pennsylvania, C=US

OpenSSL традиционно использовал по умолчанию формат с косой чертой перед каждым элементом (вместо разделяющих их запятыми), а также в прямом порядке.

/C=US/ST=Pennsylvania/L=Paoli/O=Duck Duck Go, Inc./CN=*.duckduckgo.com

но до версии 1.1.0 изменено значение по умолчанию, чтобы использовать разделители запятой с прямым порядком

C = US, ST = Pennsylvania, L = Paoli, O = "Duck Duck Go, Inc.", CN = *.duckduckgo.com 

Некоторые операции командной строки OpenSSL, например x509, поддержка других форматов отображения; см. справочную страницу в разделе "Параметры имени". В частностиx509 -nameopt oneline,dn_rev дает почти тот же формат, что и Java:

CN = *.duckduckgo.com, O = "Duck Duck Go, Inc.", L = Paoli, ST = Pennsylvania, C = US

Wireshark, если вы посмотрите только сводку для переданного сертификата (в TLS), отобразит пары атрибут = значение с полными именами вместо сокращений для атрибутов в обратном порядке, как в RFC и Java:

но если вы щелкните поля со знаком плюса, чтобы развернуть несколько уровней, вы можете увидеть структуру с каждым элементом атрибута отдельно в прямом порядке:

Именно потому, что существует и было множество вариантов формата отображения, сравнивать DN как строки - не лучшая идея. Если вам нужно сохранить его как строку, например, в базе данных, лучший способ - перестроить структурированную форму из строки - используя согласованные соглашения относительно порядка, сокращений и т. Д. - и сравнить структурированные объекты. Это станет немного проще, если вы прочитаете javadoc и увидите, что X509Certificate.getIssuerDN() и аналогично .getSubjectDN() "опорочены" (очевидно, предназначены для "устаревания") и заменены с версии Java 1.4 на .getIssuerX500Principal() а также .getSubjectX500Principal() которые используют задокументированный класс API (вместо непрозрачного внутреннего класса) javax.security.auth.x500.X500Principal с задокументированным .equals() операция.

Другие вопросы по тегам