openssl 建立连接

 

下面是server 和client 的代码。用没跑过,但是用类似的代码跑了。流程是这样的。要注意的是openssl中ssl连接建立前用阻塞的socket,建立后可以设置非阻塞。openssl每个操作后最好检查下是否成功。

/************server*************************/
#include <string.h>
#include <iostream>
#include <winsock2.h>
#include <openssl/ssl.h>
#include <openssl/x509.h>
#include <openssl/rand.h>
#include <openssl/err.h>
 
#pragma comment (lib,"WS2_32.lib")
#pragma comment( lib, "libeay32.lib" )
#pragma comment( lib, "ssleay32.lib" )
 
char buffer[10001] = {0};
 
int main()
{
SSL_library_init(); //初始化SSL库
OpenSSL_add_all_algorithms(); //支持所有算法
SSL_load_error_strings();  //提供将错误号解析为字符串的功能
SSL *ssl = NULL;
SSL_CTX *ssl_ctx = NULL;
SSL_METHOD *ssl_method = NULL;
X509 *client_cert = NULL;
//设置客户端使用的SSL版本
//ssl_method = SSLv3_server_method();
ssl_method = SSLv23_server_method();
//创建SSL上下文环境 每个进程只需维护一个SSL_CTX结构体
ssl_ctx = SSL_CTX_new(ssl_method);
 
//验证对方
SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_PEER,NULL);
 
//若验证,则放置CA证书
SSL_CTX_load_verify_locations(ssl_ctx, "cacert.pem", NULL);
 
//设置pass phrase
SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, "pass phrase");
//读取证书文件
SSL_CTX_use_certificate_file(ssl_ctx,"*****Cert.pem",SSL_FILETYPE_PEM);
 
//读取密钥文件
SSL_CTX_use_PrivateKey_file(ssl_ctx,"*****Key.pem",SSL_FILETYPE_PEM);
 
//验证密钥是否与证书一致
SSL_CTX_check_private_key(ssl_ctx);
 
/*构建随机数生成机制,WIN32平台必需*/
srand( (unsigned)time( NULL ) );
for( int i = 0;    i < 100;i++ )
seed_int[i] = rand();
RAND_seed(seed_int, sizeof(seed_int));
//设置加密方式
//SSL_CTX_set_cipher_list(ssl_ctx,"RC4-MD5");
//建立TCP服务器端、开始监听并接受客户端连接请求
 
// 初始化 Winsock.
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
{
//失败
return -1;
}
// 建立socket
server = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( server == INVALID_SOCKET )
{
//失败
WSACleanup();
return -2;
}
 
// 绑定socket
sockaddr_in service;
service.sin_family = AF_INET;
//service.sin_addr.s_addr = inet_addr("127.0.0.1");
service.sin_addr.s_addr = INADDR_ANY;
service.sin_port = htons( 8899 );
 
if ( bind( server, (SOCKADDR*) &service, sizeof(service) ) == SOCKET_ERROR )
{
//失败
closesocket(server);
return -3;
}
 
// 监听 socket
if ( listen( server, 10 ) == SOCKET_ERROR )
{
//失败
return -4;
}
 
do
{
sClient = accept(server,NULL,NULL);
Sleep(100);
}while(sClient == INVALID_SOCKET);
 
//创建当前连接的SSL结构体
ssl = SSL_new(ssl_ctx);
//将SSL绑定到套接字上
SSL_set_fd(ssl, sClient);
 
//接受SSL链接
SSL_accept(ssl);
 
//获取和释放客户端证书
client_cert = SSL_get_peer_certificate(ssl);
//打印所有加密算法的信息(可选)
std::cout<<"SSL connection using"<<SSL_get_cipher(ssl)<<std::endl;
 
X509_free(client_cert);
 
//unsigned long cmd;
//if (SOCKET_ERROR == ioctlsocket(sClient, FIONBIO, &cmd))
//{
//创建套接字时发生错误,非阻塞设置失败
//ErrorProcess();
//closesocket(sClient);
//}
 
while(true)
{
SSL_read(ssl, buffer, 10000);
memset(buffer,0,10000);
SSL_write(ssl, "hello, world!", sizeof("hello, world!"));
Sleep(1000);
 
}
 
//断开SSL链接
SSL_shutdown(ssl);
//释放当前SSL链接结构体
SSL_free(ssl);
//断开TCP链接
closesocket(sClient);
//释放SSL上下文
SSL_CTX_free(ssl_ctx);
 
return 0;
}
  1. /**************client*********************/  
  2. #include <iostream>  
  3. #include <string.h>  
  4. #include <winsock2.h>  
  5. #include <openssl/ssl.h>  
  6. #include <openssl/x509.h>  
  7. #include <openssl/rand.h>  
  8. #include <openssl/err.h>  
  9. #pragma comment (lib,"WS2_32.lib")  
  10. #pragma comment( lib, "libeay32.lib" )  
  11. #pragma comment( lib, "ssleay32.lib" )  
  12.    
  13. int main(int argc, _TCHAR* argv[])  
  14. {  
  15.    
  16. SOCKET client;  
  17. char buffer[256] = {0};  
  18. int  seed_int[100]; /*存放随机序列*/  
  19.    
  20. SSL *ssl = NULL;  
  21. SSL_CTX *ssl_ctx = NULL;  
  22. SSL_METHOD *ssl_method = NULL;  
  23. X509 *server_cert = NULL;  
  24.    
  25. SSL_library_init();        //init libraries   
  26. OpenSSL_add_all_algorithms(); //支持所有算法   
  27. SSL_load_error_strings();  //提供将错误号解析为字符串的功能   
  28.    
  29.    
  30. //设置客户端使用的SSL版本   
  31. ssl_method = SSLv3_client_method();  
  32. //创建SSL上下文环境 每个进程只需维护一个SSL_CTX结构体   
  33. ssl_ctx = SSL_CTX_new(ssl_method);  
  34. /*构建随机数生成机制,WIN32平台必需*/  
  35. srand( (unsigned)time( NULL ) );  
  36. for( int i = 0;    i < 100;i++ )  
  37. seed_int[i] = rand();  
  38. RAND_seed(seed_int, sizeof(seed_int));  
  39.    
  40.    
  41. /* Load the RSA CA certificate into the SSL_CTX structure */  
  42. /* This will allow this client to verify the server's   */  
  43. /* certificate.                             */  
  44. SSL_CTX_load_verify_locations(ssl_ctx, "cacert.pem", NULL);  
  45.    
  46. /* Set flag in context to require peer (server) certificate verification */  
  47. SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_PEER,NULL);  
  48. SSL_CTX_set_verify_depth(ssl_ctx,1);  
  49. SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, "pass phrase");  
  50. //读取证书文件   
  51. SSL_CTX_use_certificate_file(ssl_ctx,"******Cert.pem",SSL_FILETYPE_PEM);  
  52. //读取密钥文件   
  53. SSL_CTX_use_PrivateKey_file(ssl_ctx,"******Key.pem",SSL_FILETYPE_PEM);  
  54. //验证密钥是否与证书一致   
  55. SSL_CTX_check_private_key(ssl_ctx);  
  56.    
  57.    
  58. //建立TCP链接   
  59. // 初始化 Winsock.   
  60. WSADATA wsaData;  
  61. int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );  
  62. if ( iResult != NO_ERROR )  
  63. {  
  64. //AfxMessageBox("Error at WSAStartup()!");   
  65. return;  
  66. }  
  67.    
  68. // 建立socket socket.   
  69. client = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );  
  70. if ( client == INVALID_SOCKET )  
  71. {  
  72. //AfxMessageBox("Error at socket!");   
  73. WSACleanup();  
  74. return;  
  75. }  
  76.    
  77. // 连接到服务器.   
  78. sockaddr_in clientService;  
  79. clientService.sin_family = AF_INET;  
  80. clientService.sin_addr.s_addr = inet_addr( "127.0.0.1" );  
  81. clientService.sin_port = htons( 8899 );  
  82. if ( connect( client, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)  
  83. {  
  84. //AfxMessageBox( "Failed to connect!" );   
  85. WSACleanup();  
  86. return;  
  87. }  
  88.    
  89. //unsigned long cmd;   
  90. //if (SOCKET_ERROR == ioctlsocket(client, FIONBIO, &cmd))   
  91. //{   
  92. //  //AfxMessageBox( "创建套接字时发生错误,非阻塞设置失败:");   
  93. //  closesocket(client);   
  94. //}   
  95. //创建维护当前连接信息的SSL结构体   
  96. ssl = SSL_new(ssl_ctx);  
  97. //将SSL绑定到套接字上   
  98. SSL_set_fd(ssl, client);  
  99. //建立SSL链接   
  100. SSL_connect(ssl);  
  101.    
  102. //获取服务器端证书   
  103. server_cert = SSL_get_peer_certificate(ssl);  
  104.    
  105. //释放服务器端证书   
  106. X509_free(server_cert);  
  107.    
  108. unsigned long cmd;  
  109. if (SOCKET_ERROR == ioctlsocket(client, FIONBIO, &cmd))  
  110. {  
  111. //AfxMessageBox( "创建套接字时发生错误,非阻塞设置失败:");   
  112. closesocket(client);  
  113. }  
  114. while(true)  
  115. {  
  116. SSL_write(ssl, "hello, world!", sizeof("hello, world!");  
  117. SSL_read(ssl, buffer, 255);  
  118. printf("received: %s\n",buffer);  
  119. memset(buffer,0,255);  
  120.    
  121. Sleep(1000);  
  122. }  
  123. //断开SSL链接   
  124. SSL_shutdown(ssl);  
  125. //释放当前SSL链接结构体   
  126. SSL_free(ssl);  
  127. closesocket(client);  
  128. //释放上下文   
  129. SSL_CTX_free(ssl_ctx);  
  130.    
  131. return 0;  
  132. }  
  133.    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值