Java MTLS Тема и порядок издателя - PullRequest
0 голосов
/ 02 октября 2019

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

javax.net.debug=all, и я вижу, что рукопожатие прошло успешно. Однако партнер выполняет полное совпадение строк с полями «Субъект» и «Эмитент» и сравнивает их с полями в своей базе данных.

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

   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 Ответ

1 голос
/ 04 октября 2019

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

Справочная информация: сертификаты X.509 / PKIX идентифицируют Субъекта и Эмитента (а иногда и другие вещи / сущности в некоторых расширениях) с использованием структуры Отличительное имя X.500 / 501 *, также называемой X500Name, X501Name илипросто имя. Эта структура определена в ASN.1 как последовательность SEQUENCE (упорядоченная) элементов RelativeDistinguishedName, каждый из которых является официально SET (неупорядоченным) пар (SEQUENCE) типа и значения атрибута, хотя на практике наборы RDN почти всегда являются одиночными,Таким образом, имя является последовательностью типа атрибута и значения. Этот формат имени был разработан для использования в глобальной распределенной иерархической сети «каталогов», а точнее , такой как DNS , за исключением (поскольку CCITT-now-ITU-T является организацией правительственных учреждений), основанной главным образом нанациональные каталоги, основанные на стране, а не функциональные или «общие», такие как .com .org .edu .gov .mil .net, и сертификаты X.509 были разработаны как экспорт данных из этой сети каталогов, которые можно использовать в автономном режиме. На практике настоящие каталоги X.500 вообще не используются, и даже протоколы к ним, такие как LDAP (протокол облегченного доступа к каталогам), используются редко, за исключением «доменов» (Active Directory) Microsoft Windows, но сертификатов X.509включая используемый в них формат имени, широко используются в SSL-now-TLS, S / MIME и многих других приложениях.

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

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

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

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

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

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:

Wireshark unexpanded display

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

Wireshark expanded display

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

...