unix 将简单套接字转换为SSL套接字

nuypyhwy  于 2022-11-04  发布在  Unix
关注(0)|答案(5)|浏览(240)

我编写了简单的C程序,这些程序使用套接字(“客户端”和“服务器”)。(UNIX/Linux用法)
服务器端只需创建一个套接字:

  1. sockfd = socket(AF_INET, SOCK_STREAM, 0);

然后将其绑定到sockaddr:

  1. bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));

倾听(接受和阅读):

  1. listen(sockfd,5);
  2. newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
  3. read(newsockfd,buffer,255);

客户端创建套接字,然后写入套接字。
现在,我想以最简单、最田园诗般、最简洁、最快捷的方式,将这个简单的连接转换为SSL连接。
我试图将OpenSSL添加到我的项目中,但我找不到一种简单的方法来实现我想要的东西。

dkqlctbz

dkqlctbz1#

使用OpenSSL时有几个步骤。你必须制作一个SSL证书,它可以包含带有私钥的证书,确保指定证书的确切位置(这个例子在根目录中)。有很多很好的教程。

其中包括:

  1. # include <openssl/applink.c>
  2. # include <openssl/bio.h>
  3. # include <openssl/ssl.h>
  4. # include <openssl/err.h>

您需要初始化OpenSSL:

  1. void InitializeSSL()
  2. {
  3. SSL_load_error_strings();
  4. SSL_library_init();
  5. OpenSSL_add_all_algorithms();
  6. }
  7. void DestroySSL()
  8. {
  9. ERR_free_strings();
  10. EVP_cleanup();
  11. }
  12. void ShutdownSSL()
  13. {
  14. SSL_shutdown(cSSL);
  15. SSL_free(cSSL);
  16. }

现在来看看大部分的功能。你可能想在连接上添加一个while循环。

  1. int sockfd, newsockfd;
  2. SSL_CTX *sslctx;
  3. SSL *cSSL;
  4. InitializeSSL();
  5. sockfd = socket(AF_INET, SOCK_STREAM, 0);
  6. if (sockfd< 0)
  7. {
  8. //Log and Error
  9. return;
  10. }
  11. struct sockaddr_in saiServerAddress;
  12. bzero((char *) &saiServerAddress, sizeof(saiServerAddress));
  13. saiServerAddress.sin_family = AF_INET;
  14. saiServerAddress.sin_addr.s_addr = serv_addr;
  15. saiServerAddress.sin_port = htons(aPortNumber);
  16. bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
  17. listen(sockfd,5);
  18. newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
  19. sslctx = SSL_CTX_new( SSLv23_server_method());
  20. SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
  21. int use_cert = SSL_CTX_use_certificate_file(sslctx, "/serverCertificate.pem" , SSL_FILETYPE_PEM);
  22. int use_prv = SSL_CTX_use_PrivateKey_file(sslctx, "/serverCertificate.pem", SSL_FILETYPE_PEM);
  23. cSSL = SSL_new(sslctx);
  24. SSL_set_fd(cSSL, newsockfd );
  25. //Here is the SSL Accept portion. Now all reads and writes must use SSL
  26. ssl_err = SSL_accept(cSSL);
  27. if(ssl_err <= 0)
  28. {
  29. //Error occurred, log and close down ssl
  30. ShutdownSSL();
  31. }

然后,您就可以使用以下命令进行读写:

  1. SSL_read(cSSL, (char *)charBuffer, nBytesToRead);
  2. SSL_write(cSSL, "Hi :3\n", 6);

更新应该使用最符合您需求的TLS方法来呼叫SSL_CTX_new,以支援较新版本的安全性,而非SSLv23_server_method()。请参阅:OpenSSL SSL_CTX_new description

  • TLS_method(),TLS_server_method(),TLS_client_method().* 这些是通用 * 版本灵活 * SSL/TLS方法.实际使用得协议版本将协商为客户端与服务器相互支持得最高版本.支持得协议有SSLv 3,TLSv 1,TLSv1.1,TLSv1.2与TLSv1.3.
展开查看全部
smtd7mpg

smtd7mpg2#

OpenSSL是相当困难的。很容易因为没有正确地进行协商而意外地放弃所有的安全性。(见鬼,我个人被一个bug咬了一口,curl没有正确地阅读OpenSSL警报,并且不能与一些站点通信。)
如果你真的希望快速简单,那就把stud放在你的程序前面,然后就可以收工了。把SSL放在一个不同的进程中不会拖慢你的速度:http://vincent.bernat.im/en/blog/2011-ssl-benchmark.html

eimct9ow

eimct9ow3#

对于像我这样的人:
在SSL源代码中,曾经有一个例子,它位于demos/ssl/目录中,其中包含C++代码示例。现在,它只能通过历史记录获得:https://github.com/openssl/openssl/tree/691064c47fd6a7d11189df00a0d1b94d8051cbe0/demos/ssl
你可能得找到一个工作版本,我最初是在2015年11月6日发布这个答案的。我不得不编辑源代码--不多。
证书:.在demos/certs/apps/中的PEM:https://github.com/openssl/openssl/tree/master/demos/certs/apps

bwleehnv

bwleehnv4#

就像你看到的那样,这是非常麻烦的。但是“简单”的部分是,在你用OpenSSL建立了SSL/TLS会话之后,你在HTTPS的套接字上读/写所遵循的模式与你在HTTP上所遵循的模式是一样的。
不同之处在于,您使用的是SSL_read/SSL_write函数,而不是read/write函数。SSL_read/SSL_write函数将SSL指针而不是文件描述符作为其第一参数。
无论如何,这里是一个完整的Unix环境下的OpenSSL示例,包括编译/运行指令、APT依赖项和引用。
成功编译后,您将看到一个关于已弃用OpenSSL函数的警告。
成功运行后,您将看到example.com的TLS证书主题被打印到标准输出中,后跟example.com的HTML内容。
https://github.com/angstyloop/c-web/blob/main/openssl-fetch-example.c
在Ubuntu 22.04上测试。

pzfprimi

pzfprimi5#

下面是我的示例ssl套接字服务器线程(多连接)https://github.com/breakermind/CppLinux/blob/master/QtSslServerThreads/breakermindsslserver.cpp

  1. # include <pthread.h>
  2. # include <stdio.h>
  3. # include <stdlib.h>
  4. # include <string>
  5. # include <unistd.h>
  6. # include <iostream>
  7. # include <breakermindsslserver.h>
  8. using namespace std;
  9. int main(int argc, char *argv[])
  10. {
  11. BreakermindSslServer boom;
  12. boom.Start(123,"/home/user/c++/qt/BreakermindServer/certificate.crt", "/home/user/c++/qt/BreakermindServer/private.key");
  13. return 0;
  14. }
展开查看全部

相关问题