OpenSSL安全编程后如何查看是否建立SSL连接

nicholas199109 2015-05-10 10:50:03

//************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()
{
int server;
int sClient;
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 = (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,"cacert.pem",SSL_FILETYPE_PEM);

//读取密钥文件
SSL_CTX_use_PrivateKey_file(ssl_ctx,"privkey.pem",SSL_FILETYPE_PEM);

//验证密钥是否与证书一致
int valid=SSL_CTX_check_private_key(ssl_ctx);
printf("Valid:%d\n",valid);
/*构建随机数生成机制,WIN32平台必需*/
srand( (unsigned)time( NULL ) );
int seed_int[100];
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);
printf("Received:%s\n",buffer);
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;
}


//**************client*********************/
#include <iostream>
#include <string.h>
#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" )


void ShowCerts(SSL * ssl)
{
X509 *cert;
char *line;

cert = SSL_get_peer_certificate(ssl);
if (cert != NULL) {
printf("数字证书信息:\n");
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
printf("证书: %s\n", line);
//free(line);
line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);
printf("颁发者: %s\n", line);
//free(line);
X509_free(cert);
} else
printf("无证书信息!\n");
}

void main(int argc, _TCHAR* argv[])
{

int client;
char buffer[256] = {0};
int seed_int[100]; /*存放随机序列*/

SSL *ssl = NULL;
SSL_CTX *ssl_ctx = NULL;
SSL_METHOD *ssl_method = NULL;
X509 *server_cert = NULL;

SSL_library_init(); //init libraries
OpenSSL_add_all_algorithms(); //支持所有算法
SSL_load_error_strings(); //提供将错误号解析为字符串的功能


//设置客户端使用的SSL版本
ssl_method = (SSL_METHOD*)SSLv3_client_method();
//创建SSL上下文环境 每个进程只需维护一个SSL_CTX结构体
ssl_ctx = SSL_CTX_new(ssl_method);
if (ssl_ctx == NULL) {
ERR_print_errors_fp(stdout);
exit(1);
}
/*构建随机数生成机制,WIN32平台必需*/
/*srand( (unsigned)time( NULL ) );
for( int i = 0; i < 100;i++ )
seed_int[i] = rand();
RAND_seed(seed_int, sizeof(seed_int));*/


///* Load the RSA CA certificate into the SSL_CTX structure */
///* This will allow this client to verify the server's */
///* certificate. */
//SSL_CTX_load_verify_locations(ssl_ctx, "cacert.pem", NULL);

///* Set flag in context to require peer (server) certificate verification */
//SSL_CTX_set_verify(ssl_ctx,SSL_VERIFY_PEER,NULL);
//SSL_CTX_set_verify_depth(ssl_ctx,1);
//SSL_CTX_set_default_passwd_cb_userdata(ssl_ctx, "pass phrase");
////读取证书文件
//SSL_CTX_use_certificate_file(ssl_ctx,"cacert.pem",SSL_FILETYPE_PEM);
////读取密钥文件
//SSL_CTX_use_PrivateKey_file(ssl_ctx,"privkey.pem",SSL_FILETYPE_PEM);
////验证密钥是否与证书一致
//SSL_CTX_check_private_key(ssl_ctx);


//建立TCP链接
// 初始化 Winsock.
WSADATA wsaData;
int iResult = WSAStartup( MAKEWORD(2,2), &wsaData );
if ( iResult != NO_ERROR )
{
//AfxMessageBox("Error at WSAStartup()!");
return;
}

// 建立socket socket.
client = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( client == INVALID_SOCKET )
{
//AfxMessageBox("Error at socket!");
WSACleanup();
return;
}

// 连接到服务器.
sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr( "192.168.1.11" );
clientService.sin_port = htons( 8899 );
if ( connect( client, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
{
//AfxMessageBox( "Failed to connect!" );
WSACleanup();
return;
}
printf("server connected\n");
//unsigned long cmd;
//if (SOCKET_ERROR == ioctlsocket(client, FIONBIO, &cmd))
//{
// //AfxMessageBox( "创建套接字时发生错误,非阻塞设置失败:");
// closesocket(client);
//}
//创建维护当前连接信息的SSL结构体
ssl = SSL_new(ssl_ctx);
//将SSL绑定到套接字上
SSL_set_fd(ssl, client);
/* 建立 SSL 连接 */
if (SSL_connect(ssl) == -1)
ERR_print_errors_fp(stderr);
else {
printf("Connected with %s encryption\n", SSL_get_cipher(ssl));
ShowCerts(ssl);
}
int len;
//bzero(buffer, MAXBUF + 1);
strcpy(buffer, "from client->server");
/* 发消息给服务器 */
len = SSL_write(ssl, buffer, strlen(buffer));
if (len < 0)
printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",buffer, errno, strerror(errno));
else
printf("消息'%s'发送成功,共发送了%d个字节!\n",buffer, len);
Sleep(2000);
len = SSL_read(ssl, buffer, 100);
if (len > 0)
printf("接收消息成功:'%s',共%d个字节的数据\n",buffer, len);
else {
printf("消息接收失败!错误代码是%d,错误信息是'%s'\n",errno, strerror(errno));
goto finish;
}
finish:
getchar();
/* 关闭连接 */
SSL_shutdown(ssl);
SSL_free(ssl);
closesocket(client);
SSL_CTX_free(ssl_ctx);
return;
}

以上两个小程序简单实现了服务端和客户端的SSL连接,但问题是我如何验证它们是否真的建立SSL连接?浏览https网页时我可以用WireShark抓取SSL的连接信息,但这两个小程序通信时却只能抓到TCP的包

里面压根找不到SSL建立连接的过程,只是普通的TCP通信
...全文
2247 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
窝米逗佛~ 2017-01-03
  • 打赏
  • 举报
回复
都17了 都没人回答呢
peng__delphi 2015-05-22
  • 打赏
  • 举报
回复
nicholas199109 2015-05-19
  • 打赏
  • 举报
回复
都过去一个多礼拜了,没人回答吗???

4,451

社区成员

发帖
与我相关
我的任务
社区描述
云计算 云安全相关讨论
社区管理员
  • 云安全社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧