Как выполнить «Аутентификацию клиента», если я не могу предоставить закрытый ключ - PullRequest
0 голосов
/ 04 января 2019

Я хочу настроить свой локальный сервер для связи с моим клиентом.Они строят TLS-соединение, используя Openssl.Я пытаюсь реализовать двустороннюю аутентификацию, как если бы сервер проверял, что клиенту и клиенту также нужно проверять сервер.

Когда я использую сертификаты, сгенерированные мной, все работает нормально.Код выглядит следующим образом.Это код C ++ в клиенте.Я установил сертификат клиента, закрытый ключ и промежуточный сертификат.На стороне сервера я сохранил сертификат CA.

Соотношение: CA подписывает промежуточный сертификат, промежуточный сертификат подписывает сертификат клиента.

Как мы знаем, причина, по которой нам необходимо предоставить закрытый ключ клиентаесли клиент подпишет «вызов», а затем отправит на сервер.Сервер может получить открытый ключ клиента по цепочке сертификатов и использовать его для декодирования зашифрованного «вызова», чтобы проверить, совпадают ли они.Вы можете увидеть эту ссылку для подробного процесса: https://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake

Однако в моем сценарии у меня нет разрешения на получение закрытого ключа.У меня есть только API для вызова, который принимает дайджест или все, что мы хотим закодировать, в качестве ввода и возвращает строку, закодированную закрытым ключом клиента.

Поэтому я не могу передать "ClientPrivateKeyFileTest" в TLS.

Я искал исходный код openssl, но все рукопожатия были сделаны в этой функции: SSL_do_handshake (), и мне не разрешено изменять эту функцию.

// load client-side cert and key
SSL_CTX_use_certificate_file(m_ctx, ClientCertificateFileTest, SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(m_ctx, ClientPrivateKeyFileTest, SSL_FILETYPE_PEM);

// load intermediate cert
X509* chaincert = X509_new();
BIO* bio_cert = BIO_new_file(SignerCertificateFileTest, "rb");
PEM_read_bio_X509(bio_cert, &chaincert, NULL, NULL);
SSL_CTX_add1_chain_cert(m_ctx, chaincert)

m_ssl = SSL_new(m_ctx);

// get_seocket is my own API
m_sock = get_socket();

SSL_set_fd(m_ssl, m_sock)

// doing handshake and build connection
auto r = SSL_connect(m_ssl);

Я думаю, что все процессы рукопожатия будутбыть сделано после того, как я вызову SSL_connect ().Поэтому мне интересно, есть ли другой способ, которым я могу сделать, чтобы завершить аутентификацию клиента?

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

PS: API - это черный ящик на клиентском компьютере.

Еще одна вещь, в эти дни я обнаружил, что движок openssl может помочь в решении этой проблемы.Но кто-нибудь знает, какой двигатель полезен для этой проблемы?Знак EC, проверка или другие?

Окончательное обновление: я реализовал движок OpenSSL для перезагрузки EC_KEY_METHOD, чтобы я мог использовать свою собственную функцию знака.

Большое спасибо!

...