• OpenSSL socket 服务端


    这是我从网上找来改好的,需要添加 include 和 lib 路径

    需要自己手动生成 pem 文件,在注释里面有命行,自己动手。


      1 #define WIN32_LEAN_AND_MEAN
      2 
      3 #include <stdio.h>
      4 #include <stdlib.h>
      5 #include <errno.h>
      6 #include <string.h>
      7 #include <sys/types.h>
      8 #include <Windows.h>
      9 #include <WinSock2.h>
     10 #include <MSWSock.h>
     11 #include <WS2tcpip.h>
     12 #include <openssl/ssl.h>
     13 #include <openssl/err.h>
     14 #pragma comment(lib, "ws2_32.lib")
     15 #pragma comment(lib, "libssl.lib")
     16 #pragma comment(lib, "libcrypto.lib")
     17 #pragma comment(lib, "Crypt32.lib")
     18 
     19 // openssl 生成公钥和私钥的方法:
     20 // openssl genrsa -out privkey.pem 2048 
     21 // openssl req -config openssl.cnf -new -x509 -key privkey.pem -out cacert.pem -days 1095
     22 
     23 #define MAXBUF 1024
     24 
     25 /************关于本文档*********************************************
     26  ************filename: ssl-server.c
     27  *************purpose: 演示利用 OpenSSL 库进行基于 IP层的 SSL 加密通讯的方法,这是服务器端例子
     28  **********************************************************************************/
     29 
     30 #define bzero ZeroMemory
     31 #define close closesocket
     32 
     33 SSL_CTX *ctx;
     34 bool InitSslAll(char* publicPem, char* privatePem)
     35 {
     36     /* SSL 库初始化 */
     37     SSL_library_init();
     38 
     39     /* 载入所有 SSL 算法 */
     40     OpenSSL_add_all_algorithms();
     41 
     42     /* 载入所有 SSL 错误消息 */
     43     SSL_load_error_strings();
     44 
     45     /* 以 SSL V2 和 V3 标准兼容方式产生一个 SSL_CTX ,即 SSL Content Text */
     46     ctx = SSL_CTX_new(SSLv23_server_method());
     47 
     48     /* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 单独表示 V2 或 V3标准 */
     49     if (ctx == NULL) {
     50         ERR_print_errors_fp(stdout);
     51         return false;
     52     }
     53 
     54     /* 载入用户的数字证书, 此证书用来发送给客户端。 证书里包含有公钥 */
     55     if (SSL_CTX_use_certificate_file(ctx, publicPem, SSL_FILETYPE_PEM) <= 0)
     56     {
     57         ERR_print_errors_fp(stdout);
     58         return false;
     59     }
     60 
     61     /* 载入用户私钥 */
     62     if (SSL_CTX_use_PrivateKey_file(ctx, privatePem, SSL_FILETYPE_PEM) <= 0)
     63     {
     64         ERR_print_errors_fp(stdout);
     65         return false;
     66     }
     67 
     68     /* 检查用户私钥是否正确 */
     69     if (!SSL_CTX_check_private_key(ctx))
     70     {
     71         ERR_print_errors_fp(stdout);
     72         return false;
     73     }
     74     return true;
     75 }
     76 
     77 int main(int argc, char **argv){
     78     SOCKET sockfd, new_fd;
     79     socklen_t len;
     80     struct sockaddr_in my_addr, their_addr;
     81     unsigned int myport, lisnum;
     82     char buf[MAXBUF + 1];
     83 
     84     if (argv[1])
     85         myport = atoi(argv[1]);
     86     else
     87         myport = 7838;
     88     if (argv[2])
     89         lisnum = atoi(argv[2]);
     90     else
     91         lisnum = 2;
     92 
     93     InitSslAll(argv[4], argv[5]);
     94 
     95     WSADATA wsaData;
     96     int iResult = 0;
     97     iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
     98     if (iResult != NO_ERROR) {
     99         wprintf(L"Error at WSAStartup()
    ");
    100         return 1;
    101     }
    102 
    103     /* 开启一个 socket 监听 */
    104     if ((sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1)
    105     {
    106         perror("socket");
    107         exit(1);
    108     } else
    109         printf("socket created
    ");
    110 
    111     bzero(&my_addr, sizeof(my_addr));
    112     my_addr.sin_family = PF_INET;
    113     my_addr.sin_port = htons(myport);
    114     if (argv[3])
    115             inet_pton(AF_INET, argv[3], &my_addr.sin_addr.s_addr);
    116     else
    117         my_addr.sin_addr.s_addr = INADDR_ANY;
    118 
    119     if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))        == -1)
    120     {
    121         printf("bind error:%d", WSAGetLastError());
    122         exit(1);
    123     }
    124     else
    125         printf("binded
    ");
    126 
    127     if (listen(sockfd, lisnum) == -1)
    128     {
    129         printf("listen error:%d", WSAGetLastError());
    130         exit(1);
    131     } else
    132         printf("begin listen
    ");
    133 
    134         while (1)
    135         {
    136             SSL *ssl;
    137             len = sizeof(struct sockaddr);
    138 
    139             /* 等待客户端连上来 */
    140             if ((new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -1)
    141             {
    142                 printf("accept error:%d", WSAGetLastError());
    143                 exit(errno);
    144             }
    145             else
    146             {
    147                 char addr[64] = { 0 };
    148 
    149                 inet_ntop(AF_INET, &their_addr.sin_addr, addr, 64);
    150                 printf("server: got connection from %s, port %d, socket %d
    "
    151                     , addr,    ntohs(their_addr.sin_port), new_fd);
    152             }
    153 
    154 
    155             /* 基于 ctx 产生一个新的 SSL */
    156             ssl = SSL_new(ctx);
    157 
    158             /* 将连接用户的 socket 加入到 SSL */
    159 
    160             SSL_set_fd(ssl, new_fd);
    161 
    162             /* 建立 SSL 连接 */
    163 
    164             if (SSL_accept(ssl) == -1)
    165             {
    166                 perror("accept");
    167                 close(new_fd);
    168                 break;
    169             }
    170 
    171             /* 开始处理每个新连接上的数据收发 */
    172 
    173             bzero(buf, MAXBUF + 1);
    174             strcpy_s(buf, MAXBUF, "server->client");
    175 
    176             /* 发消息给客户端 */
    177             len = SSL_write(ssl, buf, strlen(buf));
    178             if (len <= 0) {
    179                 char err[256] = { 0 };
    180                 strerror_s(err, errno);
    181                 printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'
    ",
    182                     buf, errno, err);
    183                 goto finish;
    184             } else
    185                 printf("消息'%s'发送成功,共发送了%d个字节!
    ",
    186                     buf, len);
    187             bzero(buf, MAXBUF + 1);
    188 
    189             /* 接收客户端的消息 */
    190             len = SSL_read(ssl, buf, MAXBUF);
    191             if (len > 0)
    192                 printf("接收消息成功:'%s',共%d个字节的数据
    ",
    193                     buf, len);
    194             else
    195             {
    196                 char err[256] = { 0 };
    197                 strerror_s(err, errno);
    198                 printf("消息接收失败!错误代码是%d,错误信息是'%s'
    ",
    199                     errno, err);
    200             }
    201 
    202 
    203             /* 处理每个新连接上的数据收发结束 */
    204         finish:
    205 
    206             /* 关闭 SSL 连接 */
    207             SSL_shutdown(ssl);
    208             /* 释放 SSL */
    209             SSL_free(ssl);
    210 
    211             /* 关闭 socket */
    212 
    213             close(new_fd);
    214         }
    215 
    216     /* 关闭监听的 socket */
    217 
    218     close(sockfd);
    219 
    220     /* 释放 CTX */
    221 
    222     SSL_CTX_free(ctx);
    223 
    224     return 0;
    225 
    226 }
    227 
    228 
    PS:会笑的人,运气通常都会比别人好。
  • 相关阅读:
    Python 之 Django框架( Cookie和Session、Django中间件、AJAX、Django序列化)
    SAP 公司间开票 报错 :0080264464 000000 销售机构 未定义
    C++虚函数、纯虚函数,继承及多态、友元
    postgre 用户权限管理
    mysql 主从搭建
    vue 配置开发线上环境
    基于Ant Design UI框架的React项目
    postgresql数据库报“connections on Unix domain socket "/tmp/.s.PGSQL.5432"?”
    postgres 连接数查看与设置
    修改postgresql密码
  • 原文地址:https://www.cnblogs.com/thinkinc999/p/13158827.html
Copyright © 2020-2023  润新知