2

我目前正在修补什么是有效的聊天服务器。由于我不想过多地暴露我的用户,我使用 LibreSSL 的 OpenSSL 库的分支为其添加了 TLS 加密。其余代码似乎工作正常,但我认为我没有正确地做证书。

我在服务器上有一个私有/公共证书,它不仅应该用于加密通信,还可以确保服务器确实是客户端想要与之交谈的对象。这是我无法弄清楚的部分:

  1. 如何将服务器的公钥提供给客户端?它需要它来验证它正在与正确的服务器通信。还是我应该做其他事情,可能涉及根 CA 的证书?有 API 可以提供吗?我可以将公钥与可执行文件打包为.pem,但我找不到告诉 OpenSSL 用于客户端请求的公共服务器密钥或根 CA 的 API。

  2. 如何获取客户端的系统证书?现在我只是在一个.pem文件中创建了一个,但我真的不想为每个下载客户端的用户构建一个具有唯一证书的新下载。当然有一种方法可以通过一些 OpenSSL API 获取“当前用户的证书”或自动生成一个用于此用途的证书?

如果有人能指出我要使用的正确 API,那就太好了!我还会提供线索、指向类似问题的链接、教程、针对 OpenSSL-crypto-beginners 的书籍的指针、答案或示例代码。

目前,我同时使用SSL_CTX_use_certificate_file()SSL_CTX_use_PrivateKey_file()在客户端和服务器程序中设置证书。您可以在上面链接的 Github 聊天服务器存储库中看到代码,在eleven_session.cpp

4

2 回答 2

1

感谢SteffenUllrichschacker22帮助我解决这个问题。这是我在他们的指导下拼凑起来的解决方案:

连接后,客户端使用BIO_new(BIO_s_file()),BIO_read_filename()和从 PEM 文件中加载服务器的公共证书,然后将其与使用PEM_read_bio_X509_AUX()返回的证书进行比较。如果这不给出 0,客户端将中止连接,因为它没有与正确的服务器通信。SSL_get_peer_certificate()X509_cmp()

只有服务器获得证书,我使用SSL_CTX_use_certificate_file()(public) 设置并SSL_CTX_use_PrivateKey_file()指向包含公钥和私钥的同一个 PEM 文件。

我决定不使用验证回调,因为它将取代现有的证书验证,所以我也必须做那部分。load_cert()LibreSSL文件中的函数apps.c对弄清楚如何加载证书有很大帮助。

如果您有兴趣查看最终源代码,可以从我的 Git 存储库中公开获得 11 个聊天服务器和客户端

这是我第一次使用 SSL 套接字,所以如果您在这里发现任何问题,请告诉我。这个练习的重点是学习如何正确地做。

于 2014-11-21T08:49:08.327 回答
1

1:首先,您不需要将服务器的公钥提供给客户端,因为 OpenSSL API 会为您完成。您使用常规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

然后使用这个文件,就像你已经发现这两个函数一样:SSL_CTX_use_certificate_fileSSL_CTX_use_PrivateKey_file

尝试使用该.pem文件,如果仍然无法正常工作,请将其写入评论。

希望这会帮助你。

于 2014-11-20T16:39:44.703 回答