OpenSSL编程实例.docx

上传人:scccc 文档编号:14430625 上传时间:2022-02-06 格式:DOCX 页数:23 大小:29.03KB
返回 下载 相关 举报
OpenSSL编程实例.docx_第1页
第1页 / 共23页
OpenSSL编程实例.docx_第2页
第2页 / 共23页
OpenSSL编程实例.docx_第3页
第3页 / 共23页
OpenSSL编程实例.docx_第4页
第4页 / 共23页
OpenSSL编程实例.docx_第5页
第5页 / 共23页
点击查看更多>>
资源描述

《OpenSSL编程实例.docx》由会员分享,可在线阅读,更多相关《OpenSSL编程实例.docx(23页珍藏版)》请在三一文库上搜索。

1、客户端程序/#include #include using namespace std;#pragma comment (lib, )#include openssl/#pragma comment(lib, )#pragma comment(lib, )#define SERVICE_PORT 10000const int nBufSize = 512;/ 初始化版本Winsockint InitWinsock()WSADATA wsaData = 0;WORD wVer = MAKEWORD(2,2);int nRet = WSAStartup(wVer, &wsaData);if(nRe

2、t != 0)coutWinsock初始化失败,错误代码是nRetendl;return nRet;/ 创建一个套接字SOCKET CreateSocket()SOCKET hSocket = INVALID_SOCKET;hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);if(hSocket = INVALID_SOCKET)int last_err = WSAGetLastError();cout 创建套接字失败,错误代码是last_errendl;return hSocket;/ 连接到服务器int ConnectServer(SOC

3、KET hSocket)/ 填充远程套接字地址SOCKADDR_IN saServer = 0;= AF_INET;= htons(SERVICE_PORT);= inet_addr();/ 使用远程套接字地址连接到服务器int nRet = connect(hSocket, (SOCKADDR *)&saServer, sizeof(saServer);if(nRet = SOCKET_ERROR)int last_err = WSAGetLastError();cout 连接失败,错误代码是last_errendl;return nRet;bool InitOpenSSL()if(!SSL

4、_library_init()return false;SSL_load_error_strings();return true;int PasswordCB(char *buf, int size, int flag, void *userdata)/ 作者所创建的客户端程序私匙密码是const char* pass = ;if(size strlen(pass) + 1)return(0);strcpy(buf, pass);return(strlen(pass);int VerifyCB(int ok, X509_STORE_CTX *store)if(!ok)int err = X50

5、9_STORE_CTX_get_error(store);couterr:X509_verify_cert_error_string(err)endl;return ok;SSL_CTX* InitSSLContext()const SSL_METHOD *meth = NULL;SSL_CTX* ctx = NULL;meth = SSLv23_method();ctx = SSL_CTX_new(meth);/ 加载客户端程序证书链if(!SSL_CTX_use_certificate_chain_file(ctx, )cout 加载客户端程序证书链失败endl;return NULL;S

6、SL_CTX_set_default_passwd_cb(ctx, PasswordCB);/ 加载客户端程序私匙文件if(!SSL_CTX_use_PrivateKey_file(ctx, ,SSL_FILETYPE_PEM)cout 加载客户端程序私匙文件失败endl;return NULL;/ 加载客户端程序所信任的 CAif(!SSL_CTX_load_verify_locations(ctx, NULL)cout”加载客户端程序所信任的CA失败endl;return NULL;/ 加载OpenSSLM省信任的CAif(!SSL_CTX_set_default_verify_paths

7、(ctx)cout 加载 OpenSSlM省信任的 CA失败ServerCA-MyTestCA ,/所以可以明确验证深度是 2,即最多检查ServerCA和MyTestCAW个CASSL_CTX_set_verify_depth(ctx, 2);/ SSL_VERIFY_PEER 要求服务器提供证书, VerifyCB 用于输出 OpenSSL/ 握手过程中验证服务器证书链失败时的错误信息SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, VerifyCB);SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);return ctx

8、;/ 简单的校验,仅检查common namebool CheckCertificate(SSL* ssl)X509* cert = SSL_get_peer_certificate(ssl);if(cert = NULL)return false;X509_NAME* subjectName = X509_get_subject_name(cert);if(subjectName = NULL)return false;char buf256;if(X509_NAME_get_text_by_NID(subjectName, NID_commonName, buf, 256) 0 )if(s

9、trcmp(buf, serverApp) = 0)return true;return false;void DoWork(SSL* ssl)char buf256;while(true)if(!fgets(buf, sizeof(buf)/sizeof(buf0), stdin)SSL_shutdown(ssl);break;int len = strlen(buf);int nSent = 0;while(nSent len)int nRet = SSL_write(ssl, buf+nSent, len-nSent);if(nRet = 0)coutSSL_write 发生错误 end

10、l;SSL_clear(ssl);break;nSent += nRet;int main(int argc, char* argv)if(InitWinsock() != 0)return -1;SOCKET hSocket = INVALID_SOCKET;SSL_CTX* ctx = NULL;SSL* ssl = NULL;BIO* sbio = NULL;int nRet = 0;tryif(!InitOpenSSL()throw -1;ctx = InitSSLContext();if(ctx = NULL)throw -1;ssl = SSL_new(ctx);hSocket =

11、 CreateSocket();if(hSocket = INVALID_SOCKET)throw -1;if(ConnectServer(hSocket) = SOCKET_ERROR) throw -1;sbio = BIO_new_socket(hSocket, BIO_NOCLOSE);SSL_set_bio(ssl, sbio, sbio);if(SSL_connect(ssl) = 0)coutSSL 握手发生错误endl;throw -1;if(!CheckCertificate(ssl)throw -1;DoWork(ssl);catch(int excpt_err)nRet

12、= excpt_err;/if(sbio) BIO_free(sbio);if(ssl) SSL_free(ssl);if(ctx) SSL_CTX_free(ctx);if(hSocket != INVALID_SOCKET)closesocket(hSocket);WSACleanup();return 0;服务器程序/#include #include using namespace std;#pragma comment (lib, )#include openssl/ #pragma comment(lib, )#pragma comment(lib, )#define SERVIC

13、E_PORT 10000const int nBufSize = 512;/ 初始化版本Winsockint InitWinsock()WSADATA wsaData = 0;WORD wVer = MAKEWORD(2,2);int nRet = WSAStartup(wVer, &wsaData);if(nRet != 0)coutWinsock 初始化失败,错误代码是nRetendl;return nRet;/ 创建一个套接字SOCKET CreateSocket()SOCKET hSocket = INVALID_SOCKET;hSocket = socket(AF_INET, SOC

14、K_STREAM, IPPROTO_TCP);if(hSocket = INVALID_SOCKET)int last_err = WSAGetLastError();cout 创建套接字失败,错误代码是last_errendl;return hSocket;/ 绑定和监听int BindListen(SOCKET hSocket)/ 填充本地套接字地址sockaddr_in saListen = 0;= AF_INET;= htons(SERVICE_PORT);= htonl(INADDR_ANY);/ 把本地套接字地址绑定到监听套接字int nRet = bind(hSocket, (s

15、ockaddr*)&saListen, sizeof(sockaddr);if(nRet = SOCKET_ERROR)int last_err = WSAGetLastError();cout 绑定套接字失败,错误代码是last_errendl;else/ 开始监听nRet = listen(hSocket, 5);if(nRet = SOCKET_ERROR)int last_err = WSAGetLastError();cout 监听失败,错误代码是last_errendl;return nRet;/ 接收连接请求SOCKET AcceptRequest(SOCKET hSocket)

16、sockaddr_in saClient = 0;int nSALen = sizeof(sockaddr);SOCKET hClientSocketaccept(hSocket, (sockaddr*)&saClient,&nSALen);if(hClientSocket = INVALID_SOCKET)int last_err = WSAGetLastError();cout 接受连接请求失败,错误代码是last_errendl;return hClientSocket;bool InitOpenSSL()if(!SSL_library_init()return false;SSL_lo

17、ad_error_strings();return true;int PasswordCB(char *buf, int size, int flag, void *userdata)/ 作者所创建的服务器程序私匙密码是abcdefghconst char* pass = abcdefgh;if(size strlen(pass) + 1)return(0);strcpy(buf, pass);return(strlen(pass);int VerifyCB(int ok, X509_STORE_CTX *store)if(!ok)int err = X509_STORE_CTX_get_er

18、ror(store);couterr:X509_verify_cert_error_string(err)endl;return ok;SSL_CTX* InitSSLContext()const SSL_METHOD *meth = NULL;SSL_CTX* ctx = NULL;meth = SSLv23_method();ctx = SSL_CTX_new(meth);if(!SSL_CTX_use_certificate_chain_file(ctx, )cout 加载服务器程序证书链失败endl;return NULL;SSL_CTX_set_default_passwd_cb(c

19、tx, PasswordCB);/ 加载服务器程序私匙文件if(!SSL_CTX_use_PrivateKey_file(ctx, ,SSL_FILETYPE_PEM)cout 加载服务器程序私匙文件失败endl;return NULL;/ 加载服务器程序所信任的 CAif(!SSL_CTX_load_verify_locations(ctx, ,NULL)cout”加载服务器程序所信任的CA失败endl;return NULL;/加载OpenSSLM省信任的CAif(!SSL_CTX_set_default_verify_paths(ctx)cout 加载 OpenSSlM省信任的 CA失败

20、MyTestCA ,/ 所以可以明确验证深度是1,即只检查MyTestCASSL_CTX_set_verify_depth(ctx, 1);/ SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT 求客户端提供证书,/ 如果不提供的话,则校验失败。 VerifyCB 用于输出 OpenSSL/ 握手过程中验证客户端证书链失败时的错误信息SSL_CTX_set_verify(ctx,SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,VerifyCB);SSL_CTX_set_mode(ctx, SSL_MOD

21、E_AUTO_RETRY);return ctx;/ 简单的校验,仅检查common namebool CheckCertificate(SSL* ssl)X509* cert = SSL_get_peer_certificate(ssl);if(cert = NULL)return false;X509_NAME* subjectName = X509_get_subject_name(cert);if(subjectName = NULL)return false;char buf256;if(X509_NAME_get_text_by_NID(subjectName, NID_commo

22、nName, buf, 256) 0 )if(strcmp(buf, ClientApp) = 0)return true;return false;void DoWork(SSL* ssl)char buf256;while(true)- 1);int nRead = SSL_read(ssl, buf, sizeof(buf)/sizeof(buf0)if(nRead = 0)if(SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN)SSL_shutdown(ssl);elseSSL_clear(ssl);break;bufnRead = 0;cou

23、tbuf;int main(int argc, char* argv)if(InitWinsock() != 0)return -1;SOCKET hListenSocket = INVALID_SOCKET;SOCKET hClientSocket = INVALID_SOCKET;SSL_CTX* ctx = NULL;SSL* ssl = NULL;BIO* sbio = NULL;int nRet = 0;tryif(!InitOpenSSL()throw -1;ctx = InitSSLContext();if(ctx = NULL)throw -1;ssl = SSL_new(ct

24、x);hListenSocket = CreateSocket();if(hListenSocket = INVALID_SOCKET)throw -1;if(BindListen(hListenSocket) = SOCKET_ERROR)throw -1;hClientSocket = AcceptRequest(hListenSocket);if(hClientSocket = INVALID_SOCKET)throw -1;sbio = BIO_new_socket(hClientSocket, BIO_NOCLOSE);SSL_set_bio(ssl, sbio, sbio);if(

25、SSL_accept(ssl) = 0)coutSSL 握手发生错误endl;throw -1;if(!CheckCertificate(ssl)throw -1;DoWork(ssl);catch(int excpt_err)nRet = excpt_err;/if(sbio) BIO_free(sbio);if(ssl) SSL_free(ssl);if(ctx) SSL_CTX_free(ctx);if(hClientSocket != INVALID_SOCKET)closesocket(hClientSocket);if(hListenSocket != INVALID_SOCKET)closesocket(hListenSocket);WSACleanup();return 0;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 社会民生


经营许可证编号:宁ICP备18001539号-1