Ошибка сертификата SSL: ошибка подтверждения: num = 20: невозможно получить сертификат локального эмитента

11

Я пытался заставить SSL-соединение работать с сервером LDAPS (Active Directory), но у меня продолжают возникать проблемы. Я пытался использовать это:

openssl s_client -connect the.server.edu:3269 

Со следующим результатом:

verify error:num=20:unable to get local issuer certificate 

Я подумал, хорошо, хорошо, сервер - это старый производственный сервер, которому несколько лет. Может быть, CA нет. Затем я извлек сертификат из вывода в файл pem и попытался:

openssl s_client -CAfile mycert.pem -connect the.server.edu:3269

И это тоже не сработало.

Что мне не хватает? Разве это не должно работать ВСЕГДА?


источник
Для ясности, кажется, что LDAPS, когда обслуживается из Windows, не представляет сертификат CA, когда установлено соединение. Поэтому вы должны получить сертификат CA X.509, экспортировать как base64 и назначить, как описано в ответах ниже. В моем случае, используя python-ldap, вы назначаете его в области GLOBAL (не в вашем экземпляре ldap.initialize ()) следующим образом: ldap.set_option(ldap.OPT_X_TLS_CACERTFILE,'./ca_issuer_cert.pem') После этого я смог использовать STARTTLS (в пределах порта 389 LDAP), как и ожидалось.
mbrownnyc

Ответы:

4

Это то, что я вижу в качестве сертификата CA.

depth=1 /C=US/O=VeriSign, Inc./OU=VeriSign Trust Network/OU=Terms of use at //www.verisign.com/rpa (c)10/CN=VeriSign Class 3 International Server CA - G3
verify error:num=20:unable to get local issuer certificate
verify return:0

Это было имя сертификата, который я импортировал после того, как я выполнил -showcerts во второй попытке выше. Я перечислил сертификаты в хранилище ключей, выполнив это:

$JAVA_HOME/bin/keytool -list -v -keystore $JAVA_HOME/jre/lib/security/cacerts

Я вижу сертификат CA там.

Alias name: versign2006
Creation date: Jan 21, 2011
Entry type: trustedCertEntry

Owner: CN=VeriSign Class 3 International Server CA - G3, OU=Terms of use at www.verisign.com/rpa (c)10, OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US
Serial number: 641be820ce020813f32d4d2d95d67e67
Valid from: Sun Feb 07 19:00:00 EST 2010 until: Fri Feb 07 18:59:59 EST 2020
Certificate fingerprints:
  MD5:  BA:B0:65:B4:3B:9C:E8:40:30:21:7D:C5:C6:CD:3F:EB
  SHA1: B1:8D:9D:19:56:69:BA:0F:78:29:51:75:66:C2:5F:42:2A:27:71:04

Чтобы убедиться, что openssl использует хранилище ключей, которое я использую с сервером, я использую аргумент -CAfile:

openssl s_client -connect the.server.edu:3269 -CAfile $JAVA_HOME/jre/lib/security/cacerts

Зная, что в хранилище ключей Java для CA есть пароль, я попытался использовать опцию -pass pass: password, например так:

openssl s_client -connect the.server.edu:3269 -CAfile $JAVA_HOME/jre/lib/security/cacerts -pass pass:changeit

но это тоже не сработало.

Забавно, что в файле cacerts есть пароль, и openssl не жалуется, что не может прочитать файл cacerts. Это кажется подозрительным. Это или что-то еще звонит в колокол?

Брайан
источник
3

Эта ошибка является способом openssl сказать: «Я не могу следовать цепочке сертификатов до доверенного корня». Я только что сделал ту же команду с моими собственными серверами AD, и я получил полную цепочку сертификатов, но топ-сертификат имеет именно эту ошибку. Если у вас есть ключ публикации CA, подписавшего сертификат, вы можете указать его с помощью параметров -CAfileили-CApath

sysadmin1138
источник
Хорошо, спасибо за ответ. Я попробовал это. Получил сертификат CA, выполнив то же самое с параметром -showcerts, и получил другой сертификат. Это должен быть сертификат CA, верно? Попробовал, что вместо сертификата сервера в файле pem и получил такое же сообщение об ошибке. Есть еще мысли?
В этом случае вероятно, что он не проходит проверку по другой причине, например, истек срок действия.
sysadmin1138
1

Я пытался заставить SSL-соединение работать с сервером LDAPS (Active Directory), но у меня продолжают возникать проблемы. Я пытался использовать это:

Если вы используете OpenLDAP, вы можете установить:

TLS_REQCERT=never

в вашем openldap.confфайле, который указывает OpenLDAP не пытаться проверять сертификат. Есть аналогичная опция, если вы выполняете аутентификацию LDAP с Apache.

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

Что мне не хватает? Разве это не должно работать ВСЕГДА?

Я так не думаю. Хотя следующее может показаться окончательным, это действительно мой лучший гость:

То, что вы попробовали, будет работать только для самоподписанного сертификата. Поскольку сертификат на самом деле был выпущен Windows CA, попытка использовать сертификат сервера в качестве аргумента -CAfileне даст вам ничего.

Получил сертификат CA, выполнив то же самое с параметром -showcerts, и получил другой сертификат. Это должен быть сертификат CA, верно?

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

openssl x509 -in server.crt -noout -text | grep Issuer

... а затем посмотрите, совпадает ли один из других имеющихся у вас сертификатов с этим эмитентом.

larsks
источник