В настоящее время я работаю над тем, что чат-сервер. Поскольку я не хочу слишком много выставлять своих пользователей, я добавил к нему шифрование TLS, используя разветвленную библиотеку LibreSSL библиотеки OpenSSL. Остальная часть кода, кажется, работает нормально, но я думаю, что я не делаю сертификаты правильно.
У меня есть личный / публичный сертификат на сервере, который должен использоваться не только для шифрования связи, но и для того, чтобы убедиться, что сервер действительно является тем, с кем клиент хочет общаться. И это та часть, которую я не могу понять:
Как передать открытый ключ сервера клиенту? Это нужно, чтобы убедиться, что он говорит с нужным сервером. Или я должен делать что-то еще, может быть, с сертификатом корневого ЦС? Есть ли API для этого? Я могу упаковать открытый ключ с исполняемым файлом в виде .pem
, но я не могу найти API, чтобы сообщить OpenSSL об открытом ключе сервера, который будет использоваться для клиентских запросов, или о корневом CA.
Как получить сертификат системы для клиента? Прямо сейчас я только что создал один в .pem
файл, но я не хочу создавать новую загрузку с уникальным сертификатом для каждого пользователя, загружающего клиент. Конечно, есть способ получить «сертификат текущего пользователя» или автоматически сгенерировать его для этого использования через какой-нибудь OpenSSL API?
Если бы кто-нибудь мог указать мне на правильный API для использования, это было бы здорово! Я также взял бы подсказки, ссылки на похожие вопросы по SO, учебные пособия, ссылки на книги, предназначенные для начинающих OpenSSL-крипто, ответы или пример кода.
В настоящее время я использую оба SSL_CTX_use_certificate_file()
а также SSL_CTX_use_PrivateKey_file()
устанавливать сертификаты как в клиентской, так и в серверной программе. Вы можете увидеть код в связанном выше хранилище сервера чата Github, в eleven_session.cpp
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
файл, если он все еще не работает, запишите его в комментарии.
Надеюсь, что это поможет вам.
Благодаря 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, поэтому, если вы заметили что-то не так, пожалуйста, дайте мне знать. Весь смысл этого упражнения в том, чтобы научиться делать это правильно.