Отсутствует сертификат клиента: как его восстановить - PullRequest
1 голос
/ 31 марта 2019

Я работаю в команде, которая пытается подключить приложение Java J2SE к защищенному сайту корпоративных веб-служб с использованием сертификатов.Никто из членов команды не имел опыта создания сертификатов и кодирования для этого типа соединения.

Мы подготовили и отправили CSR и получили сертификат .p7b с сайта веб-службы..P7b содержит два сертификата: один для нас, выпущенный сайтом веб-сервисов, и второй для сайта веб-сервисов, выпущенный собственным СА корпоративного владельца.Оба появляются в списке хранилищ ключей ниже.На хранилище ключей ссылается пользовательский SSLContext, и код Java создает Apache HttpClient с этим SSLContext без ошибки.

Когда код Java пытается выполнить HttpGet, сайт веб-службы отклоняет SSLHandshake и завершает соединение сошибка:

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

В трассировке отладки рукопожатия на шаге 13 рукопожатия появляется сообщение:

ServerHelloDone
Warning: no suitable certificate found - continuing without client authentication
Certificate chain
Empty

Keytool перечисляет константы хранилища ключей как: (корпоративные идентификаторыотредактировано)

Keystore type: PKCS12
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: server
Creation date: Mar 28, 2019
Entry type: PrivateKeyEntry
Certificate chain length: 2
Certificate[1]:
Owner: ...
Issuer: ...
Serial number: ...
Valid from: Mon Mar 11 19:00:00 CDT 2019 until: Wed Mar 11 18:59:59 CDT 2020
Certificate fingerprints:
     SHA1: ...
     SHA256: ...
Signature algorithm name: SHA1withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions: 

#1: ObjectId: 2.16.840.1.113733.1.6.9 Criticality=false
0000: 01 01 FF                                           ...


#2: ObjectId: 2.5.29.19 Criticality=false
BasicConstraints:[
  CA:false
  PathLen: undefined
]

#3: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
  [DistributionPoint:
     [URIName: http://onsite-crl.pki.digicert.com/ATTServicesIncApplicationCertificates/LatestCRL.crl]
]]

#4: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

#5: ObjectId: 2.16.840.1.113730.1.1 Criticality=false
NetscapeCertType [
   SSL client
]

Certificate[2]:
Owner: ...
Issuer: ...
Serial number: ...
Valid from: Wed Feb 23 18:00:00 CST 2011 until: Tue Feb 23 17:59:59 CST 2021
Certificate fingerprints:
     SHA1: ...
     SHA256: ...
Signature algorithm name: SHA1withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3

Extensions: 

#1: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: 97 20 99 C2 73 2A 45 EB   E0 02 7F 47 DA 7B AB 7C  . ..s*E....G....
0010: EB 1F AF 6E                                        ...n
]
]

#2: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:true
  PathLen:0
]

#3: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
  [DistributionPoint:
     [URIName: http://onsitecrl.verisign.com/offlineca/ATTServicesIncATTServicesIncRootCA.crl]
]]

#4: ObjectId: 2.5.29.15 Criticality=true
KeyUsage [
  Key_CertSign
  Crl_Sign
]

#5: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  CN=VeriSignMPKI-2-51
]

#6: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 25 64 37 69 DB DC 57 99   43 80 79 29 90 6C B8 13  %d7i..W.C.y).l..
0010: 58 EE B6 D0                                        X...
]
]



*******************************************
*******************************************

]
}

Похоже, что в хранилище ключей есть запись для нашего личного ключа, но не сертификат клиента;перечислены только два сертификата из .p7b с сайта веб-служб.

Сообщение StackOverflow по адресу:

почему java не отправляет сертификат клиента во время рукопожатия SSL?

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

У меня нет артефакта, который идентифицирует как сертификат клиента.Процедура Oracle, приведенная по адресу:

https://docs.oracle.com/cd/E19509-01/820-3503/ggezu/index.html

, предполагает, что подписанный сертификат клиента должен был быть создан в процессе подготовки исходного CSR (шаг 3 процедуры), однако мы этого не делаем.похоже, у этого файла сертификата есть отдельный артефакт.

Я думаю, нам нужно восстановить сертификат клиента и импортировать его в правильное расположение цепочки сертификатов в хранилище ключей.Поскольку у нас, кажется, нет исходного файла, созданного при создании CSR, можно ли теперь заново создать сертификат клиента с нуля (шаг 3 - 5 процедуры Oracle) и отредактировать обратно в цепочку?Есть ли способ извлечь или восстановить сертификат клиента из оригинального CSR?

Любые вопросы, идеи или предложения очень ценятся.Спасибо.

1 Ответ

1 голос
/ 01 апреля 2019

Похоже, что в хранилище ключей есть запись для нашего личного ключа, но не сертификат клиента;перечислены только два сертификата из .p7b с сайта веб-служб.

Показанный вами PrivateKeyEntry, указанный в keytool , содержит клиентский сертификат (BC, KU и NCT) и сертификат CA, который предположительно является выдающим (родительским) сертификатом для этого клиентского сертификата.(Если вы импортировали эти сертификаты в это хранилище ключей с помощью keytool, то сертификат CA определенно является эмитентом, потому что keytool проверяет это; если вы использовали другой инструмент, должен выполнить то же требование, но не может.) Вы описываетеp7b содержит «второй для сайта веб-сервисов, выпущенного собственным CA корпоративного владельца», но (1) если бы в этом случае keytool не импортировал бы его как часть той же цепочки, и (2) это не имело бы смысла, потому чтоклиент не нуждается в выданном СА (то есть не самоподписанном) серверном сертификате в своем хранилище ключей или хранилище доверенных сертификатов, только в сертификате CA сервера в своем хранилище доверенных сертификатов, и это какотдельная запись, отсутствующая в PrivateKeyEntry клиента, даже если это общий файл.

В соответствии с вашим описанием вы получаете трассу javax.net.debug=ssl, поэтому посмотрите на ту часть трассировки, где он загружает хранилище ключей, и убедитесь, что эта запись загружается, и посмотрите на *** CertificateRequest сервера под Cert Authorities, чтобы увидеть, какие CA (s) он запрашивает (immed) до *** ServerHelloDone) и сравните это (те) с фактическим CA для цепочки в вашем хранилище ключей (неотредактированной).Поскольку вы используете Apache HttpClient, если вы используете одну из перегрузок, которая задает PrivateKeyStrategy, убедитесь, что он правильно выбирает псевдоним.

...