Взаимная аутентификация TLS - SSLV3_ALERT_UNSUPPORTED_CERTIFICATE - PullRequest
0 голосов
/ 02 июня 2018

В настоящее время я пытаюсь реализовать взаимную аутентификацию TLS между клиентом и сервером.Я сталкиваюсь с ошибкой SSL, и это не очень наглядно.StackOverflow также не имеет много вопросов, связанных с ним, поскольку в большинстве случаев это односторонний TLS в Интернете. Однако из того, что я видел, эта ошибка возникает из-за того, что что-то не так с сертификатом клиента, поэтому ниже я приложил соответствующую информацию. Если это не так, пожалуйста, дайте мне знать.

Создание сертификата клиента

Cnf моего клиента (foo.config) выглядит (с заменой всей конфиденциальной информации):

[ req ]
default_bits = 2048
default_md = sha256
prompt = no
req_extensions = req_ext
distinguished_name = dn
encrypt_key = no

[ dn ]
O=Bar
OU=User
CN=myuser@foo.com

[ req_ext ]
subjectAltName = email:myuser@foo.com
nsCertType = client, email, objsign
keyUsage = nonRepudiation, digitalSignature, keyEncipherment

Я передаю этот файл конфигурации с помощью opensslсоздать csr:

openssl req -new -sha256 -key foo.key -out foo.csr -config foo.config

И затем я отправляю его в API управления инфраструктурой для подписи сертификата x509.Я сохраняю сертификат клиента как foo.cert (он содержит цепочку доверия до центра сертификации).

Как мой клиент отправляет сертификат

Когда я отправляю запрос на открытие urllib на свой сервер,Я отправляю ssl-контекст с моим HTTPSConnection:

... # Inside some handler code
context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH,
            cafile=ROOT_CA)
context.load_cert_chain(certfile=CERT_DEST, keyfile=KEY_DEST)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = True
return http.client.HTTPSConnection(host, context=context)

Как мой флеш-сервер настраивает

Когда мой тестирующий флеш-сервер принимает контекст ssl, например, так:

executor = Flask(__name__)
context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH, cafile=TEST_CA_CERT)
context.load_cert_chain(certfile=TEST_CERT, keyfile=TEST_KEY)
context.verify_mode = ssl.CERT_REQUIRED
context.check_hostname = False
executor.run(host=host, port=port, ssl_context=context)

Он устанавливает собственные сертификаты и файлы ключей.Он также устанавливает запросы аутентификации клиента.

Полная трассировка ошибок

При выполнении во время вызова я получаю эту трассировку (заменяющую всю конфиденциальную информацию):

Traceback (most recent call last):
  File "/auto/foo/python3-rhel6/lib/python3.6/urllib/request.py", line 1318, in do_open
    encode_chunked=req.has_header('Transfer-encoding'))
  File "/auto/foo/python3-rhel6/lib/python3.6/http/client.py", line 1239, in request
    self._send_request(method, url, body, headers, encode_chunked)
  File "/auto/foo/python3-rhel6/lib/python3.6/http/client.py", line 1285, in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
  File "/auto/foo/python3-rhel6/lib/python3.6/http/client.py", line 1234, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/auto/foo/python3-rhel6/lib/python3.6/http/client.py", line 1026, in _send_output
    self.send(msg)
  File "/auto/foo/python3-rhel6/lib/python3.6/http/client.py", line 964, in send
    self.connect()
  File "/auto/foo/python3-rhel6/lib/python3.6/http/client.py", line 1400, in connect
    server_hostname=server_hostname)
  File "/auto/foo/python3-rhel6/lib/python3.6/ssl.py", line 407, in wrap_socket
    _context=self, _session=session)
  File "/auto/foo/python3-rhel6/lib/python3.6/ssl.py", line 814, in __init__
    self.do_handshake()
  File "/auto/foo/python3-rhel6/lib/python3.6/ssl.py", line 1068, in do_handshake
    self._sslobj.do_handshake()
  File "/auto/foo/python3-rhel6/lib/python3.6/ssl.py", line 689, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: SSLV3_ALERT_UNSUPPORTED_CERTIFICATE] sslv3 alert unsupported certificate (_ssl.c:833)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "./bar.py", line 375, in <module>
    start(args, overrides, threadlock)
  File "./bar.py", line 332, in start
    approved, alloc_message = Executor.approve(flow.the_portal.inst)
  File "/home/myuser/dev/bar/Executor.py", line 638, in approve
    with opener.open(request, json_request) as response:
  File "/auto/foo/python3-rhel6/lib/python3.6/urllib/request.py", line 526, in open
    response = self._open(req, data)
  File "/auto/foo/python3-rhel6/lib/python3.6/urllib/request.py", line 544, in _open
    '_open', req)
  File "/auto/foo/python3-rhel6/lib/python3.6/urllib/request.py", line 504, in _call_chain
    result = func(*args)
  File "/home/myuser/dev/bar/Auth.py", line 77, in https_open
    return self.do_open(self.getConnection, req)
  File "/auto/foo/python3-rhel6/lib/python3.6/urllib/request.py", line 1320, in do_open
    raise URLError(err)
urllib.error.URLError: <urlopen error [SSL: SSLV3_ALERT_UNSUPPORTED_CERTIFICATE] sslv3 alert unsupported certificate (_ssl.c:833)>

Если требуется дополнительная информация, пожалуйста,не стесняйтесь, дайте мне знать.Любая помощь будет оценена.

РЕДАКТИРОВАТЬ: Вот сертификат (в отредактированной форме):

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            ...
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: DC=com, DC=foo, CN=Foo Issuing CA - XXX
        Validity
            Not Before: ... 2018 GMT
            Not After : ... GMT
        Subject: O=Bar, OU=User, CN=myuser@foo.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                ...
        X509v3 extensions:
            X509v3 Key Usage:
                Key Encipherment, Data Encipherment
            X509v3 Subject Alternative Name:
                email:myuser@foo.com
            X509v3 Subject Key Identifier:
                ...
            X509v3 Authority Key Identifier:
                ...

            X509v3 CRL Distribution Points:

                Full Name:
                    ...
            Authority Information Access:
                CA Issuers - ...
                CA Issuers - ...

            X509v3 Extended Key Usage:
                TLS Web Server Authentication, TLS Web Client Authentication

Проверка этого файла с моим комплектом сертификатов говорит:

openssl verify -CAfile /.../certification_bundle.pem foo.cert
foo.cert: OK

Я использую OpenSSL v.1.0.1e-fips.Это должно поддерживать TLSv1.2.

Ответы [ 2 ]

0 голосов
/ 04 июня 2018
       X509v3 Key Usage:
            Key Encipherment, Data Encipherment

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

См. Также Рекомендуемое использование ключа для сертификата клиента .

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

keyUsage = nonRepudiation, digitalSignature, keyEncipherment

Таким образом, CA, возможно, выдал сертификат неверным способом, т.е. отличается от того, что вы запрашивали.

0 голосов
/ 02 июня 2018

Извините, я не могу комментировать, но похоже, что в вашем запросе на подпись сертификата отсутствует расширение расширенного использования ключа (EKU).Вам может потребоваться добавить:

extendedKeyUsage = clientAuth

к вам req_ext раздел.

Затем заново сгенерировать CSR и проверить с помощью openssl req -in foo.csr -text, что запрос на подпись содержит расширение EKU:

...
        X509v3 Extended Key Usage:
            TLS Web Client Authentication
...
...