把一个简单的套接字转换成SSL套接字
我写了简单的C程序,它们使用套接字('client'和'server')。 (UNIX / Linux使用)
服务器端只是创build一个套接字:
sockfd = socket(AF_INET, SOCK_STREAM, 0);
然后将其绑定到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);
客户端创build套接字,然后写入它。
现在,我想把这个简单的连接转换成一个SSL连接,以最简单,最田园,最新颖和最快捷的方式。
我试图添加OpenSSL到我的项目,但我找不到一个简单的方法来实现我想要的。
使用OpenSSL有几个步骤。 您必须拥有一个可以包含带私钥的证书的SSL证书,请务必指定证书的确切位置(本示例在根目录中)。 那里有很多很好的教程。
- 还有一个来自惠普
有些包括:
#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(ssl); SSL_free(ssl); }
现在的大部分function。 你可能想在连接上添加一个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);
OpenSSL是相当困难的。 由于没有正确地进行谈判,意外地抛弃了所有的安全措施是很容易的。 (哎呀,我已经亲自被一个错误所困扰,因为curl没有完全正确地读取OpenSSL警报,并且无法与某些站点交谈。)
如果你真的想要快速简单的话,就把你的程序放在你的程序前面。 在不同的stream程中使用SSL不会降低速度: http : //vincent.bernat.im/en/blog/2011-ssl-benchmark.html
对于像我这样的人:
如果你下载了SSL源代码,在c ++中有一个目录demos/ssl/
带有示例代码: https : //github.com/openssl/openssl/tree/master/demos/ssl
更新:他们已经删除了演示。 现在它只能通过历史logging: https : //github.com/openssl/openssl/tree/691064c47fd6a7d11189df00a0d1b94d8051cbe0/demos/ssl你可能将不得不find一个工作版本,我最初发布这个答案在2015年11月6日。编辑源代码 – 并不多。
在demos/certs/apps/
.pem demos/certs/apps/
: https : //github.com/openssl/openssl/tree/master/demos/certs/apps
有助于将正常套接字转换为使用SSL保护聊天的安全套接字的代码。 发送和recv调用套接字将被replace为ssl_read和ssl_write调用:更多: http ://www.writeulearn.com/secure-ssl-socket/
在这里我的例子ssl套接字服务器线程(多连接) https://github.com/breakermind/CppLinux/blob/master/QtSslServerThreads/breakermindsslserver.cpp
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string> #include <unistd.h> #include <iostream> #include <breakermindsslserver.h> using namespace std; int main(int argc, char *argv[]) { BreakermindSslServer boom; boom.Start(123,"/home/user/c++/qt/BreakermindServer/certificate.crt", "/home/user/c++/qt/BreakermindServer/private.key"); return 0; }