• 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;
    }
    
    /**************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" )
     
    int main(int argc, _TCHAR* argv[])
    {
     
    SOCKET 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 = SSLv3_client_method();
    //创建SSL上下文环境 每个进程只需维护一个SSL_CTX结构体
    ssl_ctx = SSL_CTX_new(ssl_method);
    /*构建随机数生成机制,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,"******Cert.pem",SSL_FILETYPE_PEM);
    //读取密钥文件
    SSL_CTX_use_PrivateKey_file(ssl_ctx,"******Key.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( "127.0.0.1" );
    clientService.sin_port = htons( 8899 );
    if ( connect( client, (SOCKADDR*) &clientService, sizeof(clientService) ) == SOCKET_ERROR)
    {
    //AfxMessageBox( "Failed to connect!" );
    WSACleanup();
    return;
    }
     
    //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链接
    SSL_connect(ssl);
     
    //获取服务器端证书
    server_cert = SSL_get_peer_certificate(ssl);
     
    //释放服务器端证书
    X509_free(server_cert);
     
    unsigned long cmd;
    if (SOCKET_ERROR == ioctlsocket(client, FIONBIO, &cmd))
    {
    //AfxMessageBox( "创建套接字时发生错误,非阻塞设置失败:");
    closesocket(client);
    }
    while(true)
    {
    SSL_write(ssl, "hello, world!", sizeof("hello, world!");
    SSL_read(ssl, buffer, 255);
    printf("received: %s
    ",buffer);
    memset(buffer,0,255);
     
    Sleep(1000);
    }
    //断开SSL链接
    SSL_shutdown(ssl);
    //释放当前SSL链接结构体
    SSL_free(ssl);
    closesocket(client);
    //释放上下文
    SSL_CTX_free(ssl_ctx);
     
    return 0;
    }
     

  • 相关阅读:
    BorderContainer 背景透明一不小心就解决了!
    C#编程应用线程与委托
    第二次SQL RAP要点
    最近的学习
    BW中传输的问题
    7月总结Dotnetnuke的研究总结
    EP学习要点记忆
    盲人摸象SAP PS模块的介绍与讨论
    如何跨Client删除数据
    如何修改Portal与BW系统的链接域名
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9410092.html
Copyright © 2020-2023  润新知