Как правильно применять сертификаты OpenSSL?

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

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

  1. Как передать открытый ключ сервера клиенту? Это нужно, чтобы убедиться, что он говорит с нужным сервером. Или я должен делать что-то еще, может быть, с сертификатом корневого ЦС? Есть ли API для этого? Я могу упаковать открытый ключ с исполняемым файлом в виде .pem, но я не могу найти API, чтобы сообщить OpenSSL об открытом ключе сервера, который будет использоваться для клиентских запросов, или о корневом CA.

  2. Как получить сертификат системы для клиента? Прямо сейчас я только что создал один в .pem файл, но я не хочу создавать новую загрузку с уникальным сертификатом для каждого пользователя, загружающего клиент. Конечно, есть способ получить «сертификат текущего пользователя» или автоматически сгенерировать его для этого использования через какой-нибудь OpenSSL API?

Если бы кто-нибудь мог указать мне на правильный API для использования, это было бы здорово! Я также взял бы подсказки, ссылки на похожие вопросы по SO, учебные пособия, ссылки на книги, предназначенные для начинающих OpenSSL-крипто, ответы или пример кода.

В настоящее время я использую оба SSL_CTX_use_certificate_file() а также SSL_CTX_use_PrivateKey_file() устанавливать сертификаты как в клиентской, так и в серверной программе. Вы можете увидеть код в связанном выше хранилище сервера чата Github, в eleven_session.cpp

2

Решение

1: Итак, прежде всего, вам не нужно передавать клиенту открытый ключ сервера, потому что API OpenSSL сделает это за вас. Вы создаете сокет, используя обычный socket функции, а затем передать его в OpenSSL, и этот сокет является идентификатором для каждого клиента, который подключается к серверу. Затем вы используете этот сокет SSL, например, в функции записи сокета SSL_write отправить зашифрованный текст клиенту.

2:
Когда я начал, я начал использовать зашифрованные сокеты, у меня также было много проблем с поиском правильного способа создания рабочего .pemфайл, так что вот моя попытка, как я это сделал. Вы должны использовать терминал Linux, и вы должны установить OpenSSL, используя sudo apt-get install openssl:

openssl genrsa -des3 -out self-ssl.key 2048
openssl req -new -key self-ssl.key -out self-ssl.csr
cp -v self-ssl.{key,original}
openssl rsa -in self-ssl.original -out self-ssl.key
rm -v self-ssl.original
openssl x509 -req -days 3650 -in self-ssl.csr -signkey self-ssl.key -out self-ssl.crt
cat self-ssl.crt self-ssl.key > server.pem

Этот файл затем используется, как вы уже узнали с этими 2 функциями: SSL_CTX_use_certificate_file а также SSL_CTX_use_PrivateKey_file

Попробуйте это с этим .pemфайл, если он все еще не работает, запишите его в комментарии.

Надеюсь, что это поможет вам.

1

Другие решения

Благодаря SteffenUllrich а также schacker22 за помощь мне с этим вопросом. Вот решение, которое я применил вместе с их руководством:

После подключения клиент использует BIO_new(BIO_s_file()), BIO_read_filename() а также PEM_read_bio_X509_AUX() загрузить публичный сертификат сервера из файла PEM, а затем сравнить его с сертификатом, возвращенным SSL_get_peer_certificate() с помощью X509_cmp(), Если это не дает 0, клиент прерывает соединение, потому что он не общается с правильным сервером.

Только сервер получает сертификат, который я установил с помощью SSL_CTX_use_certificate_file() (общедоступный) и SSL_CTX_use_PrivateKey_file() указать на один и тот же файл PEM, содержащий как открытый, так и закрытый ключ.

Я решил не использовать обратный вызов проверки, поскольку он заменил бы существующую проверку сертификата, поэтому мне придется выполнить и эту часть. load_cert() функция в LibreSSL apps.c Файл был большой помощью в выяснении, как загрузить сертификат.

Если вы заинтересованы в окончательный исходный код, это общедоступно от мой репозиторий Git для одиннадцати чат-сервера и клиента.

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

1

По вопросам рекламы [email protected]