c - 将简单的套接字变成 SSL 套接字

我编写了简单的 C 程序,它们使用套接字(“客户端”和“服务器”)。 (UNIX/Linux 用法)

服务器端简单地创建一个套接字:

sockfd = socket(AF_INET, SOCK_STREAM, 0);

然后将其绑定(bind)到 sockaddr:

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

并倾听(并接受和阅读):

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

客户端创建套接字,然后写入。

现在,我想将这个简单的连接转换为 SSL 连接,以最简单、最田园、最整洁和最快的方式。

我尝试添加 OpenSSL到我的项目,但我找不到一个简单的方法来实现我想要的。

最佳答案

使用 OpenSSL 有几个步骤。您必须制作一个 SSL 证书,该证书可以包含带有私钥的证书,请务必指定证书的确切位置(本示例将其放在根目录中)。那里有很多很好的教程。

  • Some documentation and tools from HP (see chapter 2)
  • Command line for OpenSSL

一些包括:

#include <openssl/applink.c>
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

您需要初始化 OpenSSL:

void InitializeSSL()
{
    SSL_load_error_strings();
    SSL_library_init();
    OpenSSL_add_all_algorithms();
}

void DestroySSL()
{
    ERR_free_strings();
    EVP_cleanup();
}

void ShutdownSSL()
{
    SSL_shutdown(cSSL);
    SSL_free(cSSL);
}

现在介绍大部分功能。您可能想在连接上添加一个 while 循环。

int sockfd, newsockfd;
SSL_CTX *sslctx;
SSL *cSSL;

InitializeSSL();
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd< 0)
{
    //Log and Error
    return;
}
struct sockaddr_in saiServerAddress;
bzero((char *) &saiServerAddress, sizeof(saiServerAddress));
saiServerAddress.sin_family = AF_INET;
saiServerAddress.sin_addr.s_addr = serv_addr;
saiServerAddress.sin_port = htons(aPortNumber);

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

listen(sockfd,5);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);

sslctx = SSL_CTX_new( SSLv23_server_method());
SSL_CTX_set_options(sslctx, SSL_OP_SINGLE_DH_USE);
int use_cert = SSL_CTX_use_certificate_file(sslctx, "/serverCertificate.pem" , SSL_FILETYPE_PEM);

int use_prv = SSL_CTX_use_PrivateKey_file(sslctx, "/serverCertificate.pem", SSL_FILETYPE_PEM);

cSSL = SSL_new(sslctx);
SSL_set_fd(cSSL, newsockfd );
//Here is the SSL Accept portion.  Now all reads and writes must use SSL
ssl_err = SSL_accept(cSSL);
if(ssl_err <= 0)
{
    //Error occurred, log and close down ssl
    ShutdownSSL();
}

然后您就可以使用以下方式读取或写入:

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

更新 SSL_CTX_new 应使用最适合您需要的 TLS 方法调用,以支持较新版本的安全性,而不是 SSLv23_server_method()。看: OpenSSL SSL_CTX_new description

TLS_method(), TLS_server_method(), TLS_client_method(). These are the general-purpose version-flexible SSL/TLS methods. The actual protocol version used will be negotiated to the highest version mutually supported by the client and the server. The supported protocols are SSLv3, TLSv1, TLSv1.1, TLSv1.2 and TLSv1.3.

https://stackoverflow.com/questions/7698488/

相关文章:

linux - 如何测量进程的单独 CPU 核心使用率?

linux - 连接文件并在文件之间插入新行

python - 将 Pandas 列转换为 DateTime

c - 错误 : Libtool library used but 'LIBTOOL' is und

python - 如何修改文本文件?

python - NumPy 2d 数组的切片,或者如何从 nxn 数组 (n>m) 中提取 mxm

python - 错误 "Microsoft Visual C++ 14.0 is required

python - TransactionManagementError "You can' t 在使

linux - 防止 strace 缩写参数?

linux - ssh:无法解析主机名 [主机名]:提供节点名或服务名,或未知