OpenSSL编程实例

上传人:xu****iu 文档编号:166980994 上传时间:2022-11-02 格式:DOC 页数:19 大小:40.50KB
收藏 版权申诉 举报 下载
OpenSSL编程实例_第1页
第1页 / 共19页
OpenSSL编程实例_第2页
第2页 / 共19页
OpenSSL编程实例_第3页
第3页 / 共19页
资源描述:

《OpenSSL编程实例》由会员分享,可在线阅读,更多相关《OpenSSL编程实例(19页珍藏版)》请在装配图网上搜索。

1、客户端程序/ OpenSSLClient.cpp#include #include using namespace std;#pragma comment (lib, Ws2_32.lib)#include openssl/ssl.h#pragma comment(lib, ssleay32.lib)#pragma comment(lib, libeay32.lib)#define SERVICE_PORT 10000const int nBufSize = 512;/ 初始化2.2版本Winsockint InitWinsock() WSADATA wsaData = 0; WORD wVe

2、r = 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, SOCK_STREAM, IPPROTO_TCP); if(hSocket = INVALID_SOCKET) int last_err = WSAGetLastError(); cou

3、t创建套接字失败,错误代码是last_errendl; return hSocket;/ 连接到服务器int ConnectServer(SOCKET hSocket) / 填充远程套接字地址 SOCKADDR_IN saServer = 0; saServer.sin_family = AF_INET; saServer.sin_port = htons(SERVICE_PORT); saServer.sin_addr.s_addr = inet_addr(127.0.0.1); / 使用远程套接字地址连接到服务器 int nRet = connect(hSocket, (SOCKADDR

4、*)&saServer, sizeof(saServer); if(nRet = SOCKET_ERROR) int last_err = WSAGetLastError(); cout连接失败,错误代码是last_errendl; return nRet;bool InitOpenSSL() if(!SSL_library_init() return false; SSL_load_error_strings(); return true;int PasswordCB(char *buf, int size, int flag, void *userdata) / 作者所创建的客户端程序私匙

5、密码是12345678 const char* pass = 12345678; 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_error(store); couterr:X509_verify_cert_error_string(err)endl; return ok;SSL_CTX* InitSSLContext() cons

6、t SSL_METHOD *meth = NULL; SSL_CTX* ctx = NULL; meth = SSLv23_method(); ctx = SSL_CTX_new(meth); / 加载客户端程序证书链 if(!SSL_CTX_use_certificate_chain_file(ctx, ClientAppChain.pem) cout加载客户端程序证书链失败endl; return NULL; SSL_CTX_set_default_passwd_cb(ctx, PasswordCB); / 加载客户端程序私匙文件 if(!SSL_CTX_use_PrivateKey_fi

7、le(ctx, ClientApp_PrivateKey.pem, SSL_FILETYPE_PEM) cout加载客户端程序私匙文件失败endl; return NULL; / 加载客户端程序所信任的CA if(!SSL_CTX_load_verify_locations(ctx, MyTestCA_Certificate.pem, NULL) cout加载客户端程序所信任的CA失败endl; return NULL; / 加载OpenSSL缺省信任的CA if(!SSL_CTX_set_default_verify_paths(ctx) cout 加载OpenSSL缺省信任的CA失败Ser

8、verCA-MyTestCA, / 所以可以明确验证深度是2,即最多检查ServerCA和MyTestCA两个CA SSL_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;/ 简单的校验,仅检查common namebool Che

9、ckCertificate(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(strcmp(buf, serverApp)

10、= 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发生错误endl; SSL_clea

11、r(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; try if(!InitOpenSSL() throw -1; ctx = InitSSLContext(); if(ctx = NULL) throw -1; ssl = SSL_new(ctx); h

12、Socket = 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(

13、int excpt_err) nRet = 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; -服务器程序/ OpenSSLServer.cpp#include #include using namespace std;#pragma comment (lib, Ws2_32.lib)#include openssl/ss

14、l.h#pragma comment(lib, ssleay32.lib)#pragma comment(lib, libeay32.lib)#define SERVICE_PORT 10000const int nBufSize = 512;/ 初始化2.2版本Winsockint InitWinsock() WSADATA wsaData = 0; WORD wVer = MAKEWORD(2,2); int nRet = WSAStartup(wVer, &wsaData); if(nRet != 0) coutWinsock初始化失败,错误代码是nRetendl; return nRe

15、t;/ 创建一个套接字 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 BindListen(SOCKET hSocket) / 填充本地套接字地址 sockaddr_in saListen

16、= 0; saListen.sin_family = AF_INET; saListen.sin_port = htons(SERVICE_PORT); saListen.sin_addr.s_addr = htonl(INADDR_ANY); / 把本地套接字地址绑定到监听套接字 int nRet = bind(hSocket, (sockaddr*)&saListen, sizeof(sockaddr); if(nRet = SOCKET_ERROR) int last_err = WSAGetLastError(); cout绑定套接字失败,错误代码是last_errendl; else

17、 / 开始监听 nRet = listen(hSocket, 5); if(nRet = SOCKET_ERROR) int last_err = WSAGetLastError(); cout监听失败,错误代码是last_errendl; return nRet;/ 接收连接请求SOCKET AcceptRequest(SOCKET hSocket) sockaddr_in saClient = 0; int nSALen = sizeof(sockaddr); SOCKET hClientSocket = accept(hSocket, (sockaddr*)&saClient, &nSA

18、Len); if(hClientSocket = INVALID_SOCKET) int last_err = WSAGetLastError(); cout接受连接请求失败,错误代码是last_errendl; return hClientSocket;bool InitOpenSSL() if(!SSL_library_init() return false; SSL_load_error_strings(); return true;int PasswordCB(char *buf, int size, int flag, void *userdata) / 作者所创建的服务器程序私匙密

19、码是abcdefgh const 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_error(store); couterr:X509_verify_cert_error_string(err)endl; return ok;SSL_CTX* InitSSLContext() const

20、 SSL_METHOD *meth = NULL; SSL_CTX* ctx = NULL; meth = SSLv23_method(); ctx = SSL_CTX_new(meth); / 加载服务器程序证书链 if(!SSL_CTX_use_certificate_chain_file(ctx, serverAppChain.pem) cout加载服务器程序证书链失败endl; return NULL; SSL_CTX_set_default_passwd_cb(ctx, PasswordCB); / 加载服务器程序私匙文件 if(!SSL_CTX_use_PrivateKey_fil

21、e(ctx, ServerApp_PrivateKey.pem, SSL_FILETYPE_PEM) cout加载服务器程序私匙文件失败endl; return NULL; / 加载服务器程序所信任的CA if(!SSL_CTX_load_verify_locations(ctx, MyTestCA_Certificate.pem, NULL) cout加载服务器程序所信任的CA失败endl; return NULL; / 加载OpenSSL缺省信任的CA if(!SSL_CTX_set_default_verify_paths(ctx) cout 加载OpenSSL缺省信任的CA失败MyTe

22、stCA, / 所以可以明确验证深度是1,即只检查MyTestCA SSL_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_MO

23、DE_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,

24、 NID_commonName, buf, 256) 0 ) if(strcmp(buf, ClientApp) = 0) return true; return false;void DoWork(SSL* ssl) char buf256; while(true) int nRead = SSL_read(ssl, buf, sizeof(buf)/sizeof(buf0) - 1); if(nRead = 0) if(SSL_get_shutdown(ssl) & SSL_RECEIVED_SHUTDOWN) SSL_shutdown(ssl); else SSL_clear(ssl);

25、 break; bufnRead = 0; coutbuf; 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; try if(!InitOpenSSL() throw -1; ctx = InitSSLContext();

26、if(ctx = NULL) throw -1; ssl = SSL_new(ctx); 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(hClientSoc

27、ket, BIO_NOCLOSE); SSL_set_bio(ssl, sbio, sbio); if(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;

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!