OpenSSL 在Windows 下的使用

来源:互联网 发布:拉丁美洲知乎 编辑:程序博客网 时间:2024/05/17 22:36

// 服务端#define WIN32_LEAN_AND_MEAN#include <iostream>#include <Windows.h>#include <winsock2.h>#include <openssl/rsa.h>       /* SSLeay stuff */#include <openssl/crypto.h>#include <openssl/x509.h>#include <openssl/pem.h>#include <openssl/ssl.h>#include <openssl/err.h>#define SERVER_PORT    5003// certificate & key 的存放路径// Note: 必须是全路径, 否则SSL_CTX_use_certificate_file等函数//       无法找到文件在windows平台上.// How to:// #privatekey.pem// openssl.exe genrsa -out privatekey.pem 2048// #cacert.pem// openssl.exe req -new -x509 -key privatekey.pem -out cacert.pem -days 1095 -config openssl.cnf//#define SERVER_CERTIFICATE   "c:\\cacert.pem"    #define SERVER_KEY           "c:\\privatekey.pem"#pragma comment( lib, "ws2_32.lib" )#pragma comment( lib, "libeay32.lib" )#pragma comment( lib, "ssleay32.lib" )int  main(){////////////// 初始化 //////////////SSL_CTX* ctx;SSL_METHOD *meth;SSL_load_error_strings();SSLeay_add_ssl_algorithms();meth = (SSL_METHOD *)SSLv23_server_method(); ctx = SSL_CTX_new (meth);if (!ctx) {ERR_print_errors_fp(stderr);std::cout<<"SSL_CTX_new error."<<std::endl;return -1;}if (SSL_CTX_use_certificate_file(ctx, SERVER_CERTIFICATE, SSL_FILETYPE_PEM) <= 0) {ERR_print_errors_fp(stderr);std::cout<<"SSL_CTX_use_certificate_file error."<<std::endl;return -1;}if (SSL_CTX_use_PrivateKey_file(ctx, SERVER_KEY, SSL_FILETYPE_PEM) <= 0) {ERR_print_errors_fp(stderr);std::cout<<"SSL_CTX_use_PrivateKey_file error."<<std::endl;return -1;}if (!SSL_CTX_check_private_key(ctx)) {ERR_print_errors_fp(stderr);std::cout<<"SSL_CTX_check_private_key error."<<std::endl;return -1;}///////////////////////// 建立原始的TCP连接 /////////////////////////WSADATA wsaData;SOCKET listen_socket;SOCKET accept_socket;struct sockaddr_in addr_server;struct sockaddr_in addr_client;int addr_client_len;int ret = WSAStartup( MAKEWORD(2, 2), &wsaData );if ( ret != 0 ) {std::cout<<"WSAStartup error."<<std::endl;return -1;}listen_socket = socket (AF_INET, SOCK_STREAM, 0);  if( listen_socket == INVALID_SOCKET  ) {std::cout<<"socket error."<<std::endl;return -1;}memset (&addr_server, 0, sizeof(addr_server));addr_server.sin_family           = AF_INET;addr_server.sin_addr.S_un.S_addr = INADDR_ANY;addr_server.sin_port             = htons (SERVER_PORT);        ret = bind(listen_socket, (struct sockaddr*)&addr_server, sizeof(addr_server) ); if( ret == SOCKET_ERROR )  {std::cout<<"bind error."<<std::endl;return -1;}ret = listen (listen_socket, 5); if( ret == SOCKET_ERROR ) {std::cout<<"listen error."<<std::endl;return -1;}addr_client_len = sizeof(addr_client);accept_socket = accept (listen_socket, (struct sockaddr*) &addr_client, &addr_client_len);if( accept_socket == INVALID_SOCKET  ) {std::cout<<"accept error."<<std::endl;return -1;}closesocket(listen_socket);std::cout<<" Connection from "<<addr_client.sin_addr.S_un.S_addr<<":"<<addr_client.sin_port<<std::endl;/////////////////////////////////////// TCP连接已经建立,执行Server SSL ///////////////////////////////////////SSL*     ssl;X509*    client_certificate;char*    str;ssl = SSL_new (ctx);                           if( ssl == NULL ) {std::cout<<"SSL_new error."<<std::endl;return -1;} SSL_set_fd (ssl, accept_socket);ret = SSL_accept (ssl);                     if( ret == -1 ) {std::cout<<"SSL_accept error."<<std::endl;return -1;}// 获取cipherstd::cout<<"SSL connection using: "<<SSL_get_cipher(ssl)<<std::endl;// 获取客户端的证书client_certificate = SSL_get_peer_certificate (ssl);if (client_certificate != NULL) {std::cout<<"Client certificate:"<<std::endl;str = X509_NAME_oneline (X509_get_subject_name (client_certificate), 0, 0);if( str == NULL ) {std::cout<<"X509_NAME_oneline error."<<std::endl;} else {std::cout<<"subject: "<<str<<std::endl;OPENSSL_free (str);}str = X509_NAME_oneline (X509_get_issuer_name  (client_certificate), 0, 0);if( str == NULL ) {std::cout<<"X509_NAME_oneline error."<<std::endl;} else {std::cout<<"issuer: "<<str<<std::endl;OPENSSL_free (str);}X509_free (client_certificate);} else {std::cout<<"Client does not have certificate. "<<std::endl;}//////////////////  数据交换  //////////////////char     buf [4096];ret = SSL_read (ssl, buf, sizeof(buf) - 1);    if( ret == -1 ) {std::cout<<"SSL_read error."<<std::endl;return -1;}buf[ret] = '\0';std::cout<<buf<<std::endl;ret = SSL_write (ssl, "I hear you.", strlen("I hear you.")); if( ret == -1 ) {std::cout<<"SSL_write error."<<std::endl;return -1;}/////////////// Cleanup ///////////////closesocket(accept_socket);SSL_free (ssl);SSL_CTX_free (ctx);WSACleanup();return 0;}


//客户端#define WIN32_LEAN_AND_MEAN#include <iostream>#include <winsock2.h>#include <openssl/rsa.h>       /* SSLeay stuff */#include <openssl/crypto.h>#include <openssl/x509.h>#include <openssl/pem.h>#include <openssl/ssl.h>#include <openssl/err.h>#define SERVER_IP      "127.0.0.1"#define SERVER_PORT    5003#pragma comment( lib, "ws2_32.lib" )#pragma comment( lib, "libeay32.lib" )#pragma comment( lib, "ssleay32.lib" )int main(){int ret;////////////// 初始化 //////////////SSL_CTX* ctx;SSL_METHOD *meth;SSL_load_error_strings();SSLeay_add_ssl_algorithms();meth = (SSL_METHOD *)SSLv23_client_method();ctx = SSL_CTX_new (meth);if (!ctx) {ERR_print_errors_fp(stderr);std::cout<<"SSL_CTX_new error."<<std::endl;return -1;}///////////////////////// 建立原始的TCP连接 /////////////////////////WSADATA wsaData;SOCKET client_socket;struct sockaddr_in addr_server;ret = WSAStartup( MAKEWORD(2, 2), &wsaData );if ( ret != 0 ) {std::cout<<"WSAStartup error."<<std::endl;return -1;}client_socket = socket (AF_INET, SOCK_STREAM, 0);  if( client_socket == INVALID_SOCKET  ) {std::cout<<"socket error."<<std::endl;return -1;}memset (&addr_server, 0, sizeof(addr_server));addr_server.sin_family           = AF_INET;addr_server.sin_addr.S_un.S_addr = inet_addr(SERVER_IP);addr_server.sin_port             = htons (SERVER_PORT);ret = connect(client_socket, (struct sockaddr*) &addr_server, sizeof(addr_server)); if( client_socket == SOCKET_ERROR  ) {std::cout<<"connect error."<<std::endl;return -1;}/////////////////////////////////////// TCP连接已经建立,执行Client SSL ///////////////////////////////////////SSL*     ssl;X509*    server_certificate;char*    str;ssl = SSL_new (ctx);                         if( ssl == NULL ) {std::cout<<"SSL_new error."<<std::endl;return -1;} SSL_set_fd (ssl, client_socket);ret = SSL_connect (ssl);                     if( ret == -1 ) {std::cout<<"SSL_accept error."<<std::endl;return -1;}// 接下来的获取密码和获取服务器端证书的两部是可选的,不会影响数据交换// 获取cipherstd::cout<<"SSL connection using: "<<SSL_get_cipher(ssl)<<std::endl;// 获取服务器端的证书server_certificate = SSL_get_peer_certificate (ssl);       if( server_certificate != NULL ) {std::cout<<"Server certificate:"<<std::endl;str = X509_NAME_oneline (X509_get_subject_name (server_certificate),0,0);if( str == NULL ) {std::cout<<"X509_NAME_oneline error."<<std::endl;} else {std::cout<<"subject: "<<str<<std::endl;OPENSSL_free (str);}str = X509_NAME_oneline (X509_get_issuer_name  (server_certificate),0,0);if( str == NULL ) {std::cout<<"X509_NAME_oneline error."<<std::endl;} else {std::cout<<"issuer: "<<str<<std::endl;OPENSSL_free (str);}X509_free (server_certificate);} else {std::cout<<"Server does not have certificate. we sould Esc!"<<std::endl;return -1;}//////////////////  数据交换  //////////////////char     buf [4096];ret = SSL_write (ssl, "Hello World!", strlen("Hello World!"));  if( ret == -1 ) {std::cout<<"SSL_write error."<<std::endl;return -1;}ret = SSL_read (ssl, buf, sizeof(buf) - 1);  if( ret == -1 ) {std::cout<<"SSL_read error."<<std::endl;return -1;}buf[ret] = '\0';std::cout<<buf<<std::endl;SSL_shutdown(ssl);  /* send SSL/TLS close_notify *//////////////// Cleanup ///////////////closesocket(client_socket);SSL_free (ssl);SSL_CTX_free (ctx);WSACleanup();return 0;}




原文: http://www.cppblog.com/woomsg/archive/2008/11/03/64508.html



原创粉丝点击