libevent添加ssl加密功能
来源:互联网 发布:tunnel端口的功能是 编辑:程序博客网 时间:2024/05/27 06:15
libevent的ssl加密功能
继前面两篇博文:
openssl编程之客户端
http://blog.csdn.net/fly2010love/article/details/46458805
openssl编程之服务端
http://blog.csdn.net/fly2010love/article/details/46458963
此篇博文主要介绍如何在libevent中使用openssl集成
关于libevent的使用方法,请自己百度或关注后续博文
程序如下:
#include <netinet/in.h>#include <sys/socket.h>#include <fcntl.h>#include <event2/event.h>#include <event2/buffer.h>#include <event2/bufferevent.h>#include <event2/bufferevent_ssl.h>#include <openssl/err.h>#include <openssl/ssl.h>#include <assert.h>#include <unistd.h>#include <string.h>#include <stdlib.h>#include <stdio.h>#include <errno.h>#define CA_CERT_FILE "server/ca.crt"#define SERVER_CERT_FILE "server/server.crt"#define SERVER_KEY_FILE "server/server.key"SSL* CreateSSL(evutil_socket_t& fd){ SSL_CTX* ctx = NULL; SSL* ssl = NULL; ctx = SSL_CTX_new (SSLv23_method()); if( ctx == NULL) { printf("SSL_CTX_new error!\n"); return NULL; } // 要求校验对方证书 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); // 加载CA的证书 if(!SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, NULL)) { printf("SSL_CTX_load_verify_locations error!\n"); return NULL; } // 加载自己的证书 if(SSL_CTX_use_certificate_file(ctx, SERVER_CERT_FILE, SSL_FILETYPE_PEM) <= 0) { printf("SSL_CTX_use_certificate_file error!\n"); return NULL; } // 加载自己的私钥 if(SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY_FILE, SSL_FILETYPE_PEM) <= 0) { printf("SSL_CTX_use_PrivateKey_file error!\n"); return NULL; } // 判定私钥是否正确 if(!SSL_CTX_check_private_key(ctx)) { printf("SSL_CTX_check_private_key error!\n"); return NULL; } // 将连接付给SSL ssl = SSL_new (ctx); if(!ssl) { printf("SSL_new error!\n"); return NULL; } SSL_set_fd (ssl, fd); if(SSL_accept (ssl) != 1) { int icode = -1; int iret = SSL_get_error(ssl, icode); printf("SSL_accept error! code = %d, iret = %d\n", icode, iret); return NULL; } return ssl;}void socket_read_cb(evutil_socket_t fd, short events, void *arg){ SSL* ssl = (SSL*)arg; char msg[4096]; memset(msg, 0, sizeof(msg)); int nLen = SSL_read(ssl,msg, sizeof(msg)); fprintf(stderr, "Get Len %d %s ok\n", nLen, msg); strcat(msg, "\n this is from server========server resend to client"); SSL_write(ssl, msg, strlen(msg));}void do_accept(evutil_socket_t listener, short event, void *arg){ printf("do_accept\n"); struct event_base *base = (struct event_base*)arg; struct sockaddr_storage ss; socklen_t slen = sizeof(ss); int fd = accept(listener, (struct sockaddr*)&ss, &slen); if (fd < 0) { perror("accept"); } else if (fd > FD_SETSIZE) { close(fd); } else { SSL* ssl = CreateSSL(fd); struct event *ev = event_new(NULL, -1, 0, NULL, NULL); //将动态创建的结构体作为event的回调参数 event_assign(ev, base, fd, EV_READ | EV_PERSIST, socket_read_cb, (void*)ssl); event_add(ev, NULL); }}void run(void){ evutil_socket_t listener; struct sockaddr_in sin; struct event_base *base; struct event *listener_event; base = event_base_new(); if (!base) return; /*XXXerr*/ sin.sin_family = AF_INET; sin.sin_addr.s_addr = 0; sin.sin_port = htons(8080); listener = socket(AF_INET, SOCK_STREAM, 0); evutil_make_socket_nonblocking(listener);#ifndef WIN32 { int one = 1; setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); }#endif if (bind(listener, (struct sockaddr*)&sin, sizeof(sin)) < 0) { perror("bind"); return; } if (listen(listener, 16)<0) { perror("listen"); return; } listener_event = event_new(base, listener, EV_READ|EV_PERSIST, do_accept, (void*)base); event_add(listener_event, NULL); event_base_dispatch(base);}int main(int argc, char **argv){ setvbuf(stdout, NULL, _IONBF, 0); SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); run(); return 0;}
编写makefile或者直接使用命令进行编译,得到可执行文件test
libevent服务端:
[root@localhost LibeventSSL]# ./test do_acceptGet Len 56 this is from client+++++++++++++++client send to server okGet Len 0 okGet Len 0 ok[root@localhost LibeventSSL]#
客户端:
[root@localhost SSLTestC]# ./test Server Running in LINUXSSL_CTX_load_verify_locations start!Get Len 108 this is from client+++++++++++++++client send to server this is from server========server resend to client ok[root@localhost SSLTestC]#
表明客户端跟服务器已经正常通信,同样的,进行抓包分析的话,得到只能是
不可识别的乱码,表明通信会话已经加密,ssl功能已经生效
此篇博文跟前面的 openssl编程之服务端有一个需要注意的地方,若socket为
非阻塞,在进行SSL_accept和SSL_read SSL_wirte时需要注意,此程序只是实现了加密和通信,并未处理服务器连接的问题,比如客户端关闭连接等,表现形式如:服务器端打印了两次的:
Get Len 0 okGet Len 0 ok
后面面将专门
写一篇博文进行讲解
0 0
- libevent添加ssl加密功能
- libevent的ssl加密功能
- ssl加密
- SSL加密
- 十大免费SSL证书:网站免费添加HTTPS加密
- 十大免费SSL证书:网站免费添加HTTPS加密
- 为SQLite数据库添加加密功能
- 为SQLite数据库添加加密功能
- android mosquitto客户端使用SSL功能的具体操作总结(android mqtt ssl 加密)
- libevent功能使用简介
- libevent功能使用简介
- 为QT中的sqlite数据库添加加密功能
- SSL加密通讯协议
- ssl加密的方法
- ssl加密的方法
- SSL 加密过程 原理
- ssl加密协议
- ssl加密的方法
- 实时系统HBase读写优化--大量写入无障碍
- Excel Sheet Column Number
- LeetCode 之 Add Binary — C 实现
- 强类型的 数据行的写法
- Swift入门基础语法
- libevent添加ssl加密功能
- 辞职
- 敏捷测试与传统测试的区别
- python join字符连接函数的使用方法
- Java集合类
- 进度计划管理软件 PowerPlan (包含GRID,甘特图,直方图,网络图,跟踪逻辑,时标概要图等功能)
- ERROR: Android Source Generator: [project] AndroidManifest.xml file not found
- 拥抱PBO(基于项目的组织)聚焦核心价值创造
- Qt图形框架资料02