90行代码实现C语言版https服务器,基于openssl

为了实现C语言版的https服务器(ubuntu linux),我查了很多资料,最后发现是非常简单好写的,在此向大家做个分享。

首先大致了解一下https的工作原理,下面这张图解释得非常好。

 

而openssl又对上面这张图里的一些功能进行了合并封装,让我们用起来更加方便简洁。

首先我们需要安装openssl开发包:

apt install openssl libssl-dev

然后就可以编译下面的mini版https server了 (https.c)

/*
gcc https.c -lssl -lcrypto   -o https
*/

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <signal.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>

#define BufSize 30 * 1024

int create_socket_listen(int port)
{
  int s;
  struct sockaddr_in addr;

  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);
  addr.sin_addr.s_addr = htonl(INADDR_ANY);

  s = socket(AF_INET, SOCK_STREAM, 0);  if (s < 0) {   perror("Unable to create socket");  exit(EXIT_FAILURE);  }
  if (bind(s, (struct sockaddr*)&addr, sizeof(addr)) < 0) {  perror("Unable to bind");  exit(EXIT_FAILURE); }
  if (listen(s, 1) < 0) { perror("Unable to listen"); exit(EXIT_FAILURE);   }

  return s;
}


SSL_CTX* initSSL(const char* cert, const char* key)
{
  //todo 可能存在泄露
  SSL_CTX* ctx;


  /* SSL 库初始化 */
  SSL_library_init();
  /* 载入所有 SSL 算法 */
  OpenSSL_add_all_algorithms();
  /* 载入所有 SSL 错误消息 */
  SSL_load_error_strings();
  /* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text, 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */
  ctx = SSL_CTX_new(SSLv23_server_method()); if (ctx == NULL) { ERR_print_errors_fp(stdout);  return NULL; }
  

  /* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */
  if (SSL_CTX_use_certificate_file(ctx, cert, SSL_FILETYPE_PEM) <= 0) {  ERR_print_errors_fp(stdout);  return NULL;  }
  /* 载入用户私钥 */
  if (SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM) <= 0) {   ERR_print_errors_fp(stdout);   return NULL;  }
  /* 检查用户私钥是否正确 */
  if (!SSL_CTX_check_private_key(ctx)) {  ERR_print_errors_fp(stdout);  return NULL; }


  return ctx;
}


int main(int argc, char** argv)
{
  int port = 5555;
  int sock;
  SSL_CTX* ctx;
  char buf[BufSize];

  /* Ignore broken pipe signals */
  signal(SIGPIPE, SIG_IGN);

  ctx = initSSL("./fullchain.pem", "./privkey.pem"); if (ctx == NULL) { return 0; }

  sock = create_socket_listen(port);

  /* Handle connections */
  while (1) 
  {
    struct sockaddr_in addr;
    unsigned int len = sizeof(addr);
    SSL* ssl;
    const char reply[] = "HTTP/1.1 200 OK\r\nDate: Fri, 22 May 2009 06:07:21 GMT\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n<html><head></head><body>hello world</body></html>";

    int client = accept(sock, (struct sockaddr*)&addr, &len);  if (client < 0) {  perror("Unable to accept"); exit(EXIT_FAILURE);  }

    ssl = SSL_new(ctx); SSL_set_fd(ssl, client);
    if (SSL_accept(ssl) <= 0) { ERR_print_errors_fp(stderr); goto end; }

    int size = SSL_read(ssl, buf, BufSize); printf("ssl_read(%d): \n%s\n", size, buf); 

    SSL_write(ssl, reply, strlen(reply));

  end:
    SSL_shutdown(ssl);  SSL_free(ssl);  close(client);
  }

  close(sock);
  SSL_CTX_free(ctx);
}

编译命令:

gcc https.c -lssl -lcrypto   -o https

运行前需要准备好证书fullchain.pem和私钥privkey.pem两个文件,运行:

./https

  • 5
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
要使用C语言OpenSSL实现HTTPS服务器,需要以下步骤: 1. 生成服务器私钥和证书:使用OpenSSL命令工具生成服务器私钥和自签名证书,例如: ``` openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt ``` 2. 初始化OpenSSL库:在程序开始时,调用OpenSSL库的初始化函数,例如: ``` SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); ``` 3. 创建SSL上下文:使用OpenSSL库创建SSL上下文,例如: ``` SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM); SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM); ``` 4. 创建TCP服务器:使用C语言的套接字API创建TCP服务器,例如: ``` int sockfd = socket(AF_INET, SOCK_STREAM, 0); struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(443); bind(sockfd, (struct sockaddr *)&addr, sizeof(addr)); listen(sockfd, 10); ``` 5. 处理SSL握手:使用OpenSSL库处理SSL握手过程,例如: ``` int connfd = accept(sockfd, NULL, NULL); SSL *ssl = SSL_new(ctx); SSL_set_fd(ssl, connfd); SSL_accept(ssl); ``` 6. 处理HTTP请求:在SSL握手成功后,读取客户端发送的HTTP请求并处理,例如: ``` char buf[1024]; SSL_read(ssl, buf, sizeof(buf)); // 处理HTTP请求并发送响应 SSL_write(ssl, response, strlen(response)); ``` 7. 关闭SSL连接:在处理完HTTP请求后,关闭SSL连接,例如: ``` SSL_shutdown(ssl); SSL_free(ssl); close(connfd); ``` 以上是实现HTTPS服务器的一般步骤,具体实现细节可能会因为不同的情况而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qiuzen

您的资助将帮助我创作更好的作品

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值