下面是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\n",buffer);
memset(buffer,0,255);
 
Sleep(1000);
}
//断开SSL链接
SSL_shutdown(ssl);
//释放当前SSL链接结构体
SSL_free(ssl);
closesocket(client);
//释放上下文
SSL_CTX_free(ssl_ctx);
 
return 0;
}
 

openssl指定证书密码建立连接的更多相关文章

  1. AnyConnect无法与指定的安全网关建立连接(转)

    原文:https://www.cnblogs.com/dumuqiao/p/4020547.html Cisco的VPN客户端最近报“AnyConnect was not able to establ ...

  2. JDBC详解系列(三)之建立连接(DriverManager.getConnection)

      在JDBC详解系列(一)之流程中,我将数据库的连接分解成了六个步骤. JDBC流程: 第一步:加载Driver类,注册数据库驱动: 第二步:通过DriverManager,使用url,用户名和密码 ...

  3. Security基础(四):OpenSSL及证书服务常用系统监控命令、搭建nagios监控服务器、配置文件及插件使用、监控远程主机的公有数据、监控远程主机的私有数据

    一.OpenSSL及证书服务常用系统监控命令 目标: 本案例要求练习常用的系统监控命令完成以下任务: 使用vmstat命令监控内存及磁盘I/O信息 使用iostat命令监控CPU处理器及磁盘的I/O信 ...

  4. Security基础(三):OpenSSL及证书服务、邮件TLS/SSL加密通信

    一.OpenSSL及证书服务 目标: 本案例要求熟悉OpenSSL工具的基本使用,完成以下任务操作: 使用OpenSSL加密/解密文件 搭建企业自有的CA服务器,为颁发数字证书提供基础环境 方案: 使 ...

  5. 使用 openssl 生成证书

    一.openssl 简介 目前最流行的 SSL 密码库工具官网:https://www.openssl.org/source/ 构成部分 密码算法库 密钥和证书封装管理功能 SSL通信API接口 用途 ...

  6. 使用 openssl 生成证书(转)

    一.openssl 简介 openssl 是目前最流行的 SSL 密码库工具,其提供了一个通用.健壮.功能完备的工具套件,用以支持SSL/TLS 协议的实现.官网:https://www.openss ...

  7. windows下OpenSSL加密证书安装步骤与使用方法

    OpenSSL加密证书一般用于签名认证,含私钥和公钥.在Linux系统中,OpenSSL一般是已经安装好了,可以直接使用.而在Windows系统中,是需要安装使用的. 最近在使用支付平台时,用到了Op ...

  8. 对称、非对称加密算,openssl生成证书(笔记)

    对称加密算法 1.密钥只有一个,加密和解密都需要同一个密钥2.DES,IDEA,AES3.明文+密钥=密文, 密文+密钥=明文4.加密速度快,系统开销小,适用大量数据的加密 非对称加密算法1.密钥由公 ...

  9. PHP与MySql建立连接

    通过PHP脚本建立与一个MySQL数据库的连接时,数据库服务器的主机位置(在本地就是localhost).用户名(root).密码.和数据库名是必须的.一旦建立连接,脚本就能执行SQL命令.二者联系的 ...

随机推荐

  1. 实现ModelDriver接口的功能(转)

    ModelDriver接口 来自com.opensymphony.xwork2.ModelDriven.是xwork-2.1.2-750.jar包的东西. 下面是源码: package com.ope ...

  2. jQuery使用ajaxSubmit()提交表单(在不希望页面跳转的情况下)

    原文:http://www.jb51.net/article/48728.htm ajaxSubmit(obj)方法是jQuery的一个插件jquery.form.js里面的方法,所以使用此方法需要先 ...

  3. js实现全选checkbox

    js代码 function selectAllCheckBox(parentid) { var PID = document.getElementById(parentid); var cb = PI ...

  4. UVa 11396 爪分解(二分图判定)

    https://vjudge.net/problem/UVA-11396 题意: 给出n个结点的简单无向图,每个点的度数均为3.你的任务是判断能否把它分解成若干爪.每条边必须属于一个爪,但同一个点可以 ...

  5. poj 1050 To the Max 最大子矩阵和 经典dp

    To the Max   Description Given a two-dimensional array of positive and negative integers, a sub-rect ...

  6. linux安装数据库删除

    https://blog.csdn.net/qq_40550973/article/details/80721014 卸载mysql .快速删除 yum remove mysql mysql-serv ...

  7. url传递数据类型

    php中传递数据,get或post方式为啥用字符串传递,为什么不能直接用数组形式,用的话可以吗

  8. mvn deploy返回400错误的几种可能

    user credentials are wrong url to server is wrong user does not have access to the deployment reposi ...

  9. PHP 数组遍历 foreach 语法结构

    foreach 语法结构用于遍历数组. foreach() PHP foreach() 语法结构用于遍历操作或输出数组,foreach() 仅能用于遍历数组或对象,当试图将其用于其它数据类型或者一个未 ...

  10. mock数据

    作为前端经常需要模拟后台数据,我们称之为mock.通常的方式为自己搭建一个服务器,返回我们想要的数据. 在这里我们使用node.js来实现 http://www.cnblogs.com/bsn-hua ...