基于Gmssl庫靜態編譯,實現服務端和客戶端之間的SSL通信

前情提要

  • ?將gmssl庫采取靜態編譯的方式,存儲在/usr/local/gmssl路徑下,核心文件涵蓋 include、lib和bin等
  • Ubuntu安裝GmSSL庫適用于ubuntu18和ubuntu20版本_MY CUP OF TEA的博客-CSDN博客?

代碼

?server

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>#define MAXBUF 1024void ShowCerts(SSL * ssl)
{X509 *cert;char *line;cert = SSL_get_peer_certificate(ssl);// SSL_get_verify_result()是重點,SSL_CTX_set_verify()只是配置啟不啟用并沒有執行認證,調用該函數才會真證進行證書認證// 如果驗證不通過,那么程序拋出異常中止連接if(SSL_get_verify_result(ssl) == X509_V_OK){printf("證書驗證通過\n");}if (cert != NULL) {printf("數字證書信息:\n");line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);printf("證書: %s\n", line);free(line);line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);printf("頒發者: %s\n", line);free(line);X509_free(cert);} elseprintf("無證書信息!\n");
}int main(int argc, char **argv) {int sockfd, new_fd;socklen_t len;struct sockaddr_in my_addr, their_addr;unsigned int myport, lisnum;char buf[MAXBUF + 1];SSL_CTX *ctx;if (argv[1])myport = atoi(argv[1]);elsemyport = 7838;if (argv[2])lisnum = atoi(argv[2]);elselisnum = 2;/* SSL 庫初始化 */SSL_library_init();/* 載入所有 SSL 算法 */OpenSSL_add_all_algorithms();/* 載入所有 SSL 錯誤消息 */SSL_load_error_strings();/* 以 SSL V2 和 V3 標準兼容方式產生一個 SSL_CTX ,即 SSL Content Text */ctx = SSL_CTX_new(SSLv23_server_method());/* 也可以用 SSLv2_server_method() 或 SSLv3_server_method() 單獨表示 V2 或 V3標準 */if (ctx == NULL) {ERR_print_errors_fp(stdout);exit(1);}// 雙向驗證// SSL_VERIFY_PEER---要求對證書進行認證,沒有證書也會放行// SSL_VERIFY_FAIL_IF_NO_PEER_CERT---要求客戶端需要提供證書,但驗證發現單獨使用沒有證書也會放行SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);// 設置信任根證書if (SSL_CTX_load_verify_locations(ctx, "/home/chy-cpabe/ssl_server_client.openssl_bak/ca/ca.crt",NULL)<=0){ERR_print_errors_fp(stdout);exit(1);}/* 載入用戶的數字證書, 此證書用來發送給客戶端。 證書里包含有公鑰 */if (SSL_CTX_use_certificate_file(ctx, argv[3], SSL_FILETYPE_PEM) <= 0) {ERR_print_errors_fp(stdout);exit(1);}/* 載入用戶私鑰 */if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0) {ERR_print_errors_fp(stdout);exit(1);}/* 檢查用戶私鑰是否正確 */if (!SSL_CTX_check_private_key(ctx)) {ERR_print_errors_fp(stdout);exit(1);}/* 開啟一個 socket 監聽 */if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {perror("socket");exit(1);} elseprintf("socket created\n");bzero(&my_addr, sizeof(my_addr));my_addr.sin_family = PF_INET;my_addr.sin_port = htons(myport);my_addr.sin_addr.s_addr = INADDR_ANY;if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr))== -1) {perror("bind");exit(1);} elseprintf("binded\n");if (listen(sockfd, lisnum) == -1) {perror("listen");exit(1);} elseprintf("begin listen\n");while (1) {SSL *ssl;len = sizeof(struct sockaddr);/* 等待客戶端連上來 */if ((new_fd = accept(sockfd, (struct sockaddr *) &their_addr, &len))== -1) {perror("accept");exit(errno);} elseprintf("server: got connection from %s, port %d, socket %d\n",inet_ntoa(their_addr.sin_addr), ntohs(their_addr.sin_port),new_fd);/* 基于 ctx 產生一個新的 SSL */ssl = SSL_new(ctx);/* 將連接用戶的 socket 加入到 SSL */SSL_set_fd(ssl, new_fd);/* 建立 SSL 連接 */if (SSL_accept(ssl) == -1) {perror("accept");close(new_fd);break;}ShowCerts(ssl);/* 開始處理每個新連接上的數據收發 */bzero(buf, MAXBUF + 1);strcpy(buf, "server->client");/* 發消息給客戶端 */len = SSL_write(ssl, buf, strlen(buf));if (len <= 0) {printf("消息'%s'發送失敗!錯誤代碼是%d,錯誤信息是'%s'\n", buf, errno,strerror(errno));goto finish;} elseprintf("消息'%s'發送成功,共發送了%d個字節!\n", buf, len);bzero(buf, MAXBUF + 1);/* 接收客戶端的消息 */len = SSL_read(ssl, buf, MAXBUF);if (len > 0)printf("接收消息成功:'%s',共%d個字節的數據\n", buf, len);elseprintf("消息接收失敗!錯誤代碼是%d,錯誤信息是'%s'\n",errno, strerror(errno));/* 處理每個新連接上的數據收發結束 */finish:/* 關閉 SSL 連接 */SSL_shutdown(ssl);/* 釋放 SSL */SSL_free(ssl);/* 關閉 socket */close(new_fd);}/* 關閉監聽的 socket */close(sockfd);/* 釋放 CTX */SSL_CTX_free(ctx);return 0;
}

client

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/socket.h>
#include <resolv.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <openssl/ssl.h>
#include <openssl/err.h>#define MAXBUF 1024void ShowCerts(SSL * ssl)
{X509 *cert;char *line;cert = SSL_get_peer_certificate(ssl);// SSL_get_verify_result()是重點,SSL_CTX_set_verify()只是配置啟不啟用并沒有執行認證,調用該函數才會真證進行證書認證// 如果驗證不通過,那么程序拋出異常中止連接if(SSL_get_verify_result(ssl) == X509_V_OK){printf("證書驗證通過\n");}if (cert != NULL) {printf("數字證書信息:\n");line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);printf("證書: %s\n", line);free(line);line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0);printf("頒發者: %s\n", line);free(line);X509_free(cert);} elseprintf("無證書信息!\n");
}int main(int argc, char **argv)
{int sockfd, len;struct sockaddr_in dest;char buffer[MAXBUF + 1];SSL_CTX *ctx;SSL *ssl;if (argc != 5) {printf("參數格式錯誤!正確用法如下:\n\t\t%s IP地址 端口\n\t比如:\t%s 127.0.0.1 80\n此程序用來從某個""IP 地址的服務器某個端口接收最多 MAXBUF 個字節的消息",argv[0], argv[0]);exit(0);}/* SSL 庫初始化,參看 ssl-server.c 代碼 */SSL_library_init();OpenSSL_add_all_algorithms();SSL_load_error_strings();ctx = SSL_CTX_new(SSLv23_client_method());if (ctx == NULL) {ERR_print_errors_fp(stdout);exit(1);}// 雙向驗證// SSL_VERIFY_PEER---要求對證書進行認證,沒有證書也會放行// SSL_VERIFY_FAIL_IF_NO_PEER_CERT---要求客戶端需要提供證書,但驗證發現單獨使用沒有證書也會放行SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);// 設置信任根證書if (SSL_CTX_load_verify_locations(ctx, "/home/chy-cpabe/ssl_server_client.openssl_bak/ca/ca.crt",NULL)<=0){ERR_print_errors_fp(stdout);exit(1);}/* 載入用戶的數字證書, 此證書用來發送給客戶端。 證書里包含有公鑰 */if (SSL_CTX_use_certificate_file(ctx, argv[3], SSL_FILETYPE_PEM) <= 0) {ERR_print_errors_fp(stdout);exit(1);}/* 載入用戶私鑰 */if (SSL_CTX_use_PrivateKey_file(ctx, argv[4], SSL_FILETYPE_PEM) <= 0) {ERR_print_errors_fp(stdout);exit(1);}/* 檢查用戶私鑰是否正確 */if (!SSL_CTX_check_private_key(ctx)) {ERR_print_errors_fp(stdout);exit(1);}/* 創建一個 socket 用于 tcp 通信 */if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {perror("Socket");exit(errno);}printf("socket created\n");/* 初始化服務器端(對方)的地址和端口信息 */bzero(&dest, sizeof(dest));dest.sin_family = AF_INET;dest.sin_port = htons(atoi(argv[2]));if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) {perror(argv[1]);exit(errno);}printf("address created\n");/* 連接服務器 */if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) {perror("Connect ");exit(errno);}printf("server connected\n");/* 基于 ctx 產生一個新的 SSL */ssl = SSL_new(ctx);SSL_set_fd(ssl, sockfd);/* 建立 SSL 連接 */if (SSL_connect(ssl) == -1)ERR_print_errors_fp(stderr);else {printf("Connected with %s encryption\n", SSL_get_cipher(ssl));ShowCerts(ssl);}/* 接收對方發過來的消息,最多接收 MAXBUF 個字節 */bzero(buffer, MAXBUF + 1);/* 接收服務器來的消息 */len = SSL_read(ssl, buffer, MAXBUF);if (len > 0)printf("接收消息成功:'%s',共%d個字節的數據\n",buffer, len);else {printf("消息接收失敗!錯誤代碼是%d,錯誤信息是'%s'\n",errno, strerror(errno));goto finish;}bzero(buffer, MAXBUF + 1);strcpy(buffer, "from client->server");/* 發消息給服務器 */len = SSL_write(ssl, buffer, strlen(buffer));if (len < 0)printf("消息'%s'發送失敗!錯誤代碼是%d,錯誤信息是'%s'\n",buffer, errno, strerror(errno));elseprintf("消息'%s'發送成功,共發送了%d個字節!\n",buffer, len);finish:/* 關閉連接 */SSL_shutdown(ssl);SSL_free(ssl);close(sockfd);SSL_CTX_free(ctx);return 0;
}

gmssl庫靜態編譯的命令

  • server:
    • sudo gcc ssl_server.cpp -o server -I/usr/local/include/openssl -lpthread -L/usr/local/gmssl/lib -l:libssl.a -l:libcrypto.a -ldl
  • client:
    • sudo gcc ssl_client.cpp -o client -I/usr/local/include/openssl -lpthread -L/usr/local/gmssl/lib -l:libssl.a -l:libcrypto.a -ldl

執行

  • server:
    • sudo ./server 7838 1 /home/chy-cpabe/ssl_server_client.openssl_bak/server/pem/server.crt /home/chy-cpabe/ssl_server_client.openssl_bak/server/pem/server_rsa_private.pem.unsecure
  • client:
    • sudo ./client 127.0.0.1 7838 /home/chy-cpabe/ssl_server_client.openssl_bak/client/pem/client.crt /home/chy-cpabe/ssl_server_client.openssl_bak/client/pem/client_rsa_private.pem.unsecure


參考鏈接

  • pthread庫 如果不使用會報 thread相關的錯誤,應該由于包依賴導致的問題
  • 問題解決: 對‘pthread_create’未定義的引用_話題在繞彎的博客-CSDN博客?

  • 如何指定靜態庫
  • GmSSL相遇(1) - 代碼先鋒網
  • 編譯順序 ssl在crypto之前,以及使用 -ldl,否則報錯如下
  • g++編譯時對'xxxx'未定義的引用問題(undefined reference to) - 豆奶特

?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/445904.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/445904.shtml
英文地址,請注明出處:http://en.pswp.cn/news/445904.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

禪道備份功能_更新禪道燃盡圖及數據備份

Last login: Fri May 29 13:52:16 on ttys000mazhenguodeMacBook-Pro:~ mazhenguo$ ssh root192.168.1.2 //登錄服務器root192.168.1.2’s password: //輸入服務器密碼Last login: Fri May 29 13:52:20 2015 from 192.168.1.251[rootmazhenguo ~]# cd /home/app/192.168.1.2/ze…

基于SM2證書實現SSL通信

參考鏈接 ?????基于openssl和國密算法生成CA、服務器和客戶端證書_MY CUP OF TEA的博客-CSDN博客基于上述鏈接&#xff0c;使用國密算法生成CA、服務器和客戶端證書&#xff0c;并實現簽名認證openssl實現雙向認證教程&#xff08;服務端代碼客戶端代碼證書生成&#xff…

列寬一字符等于多少厘米_Excel中行高與列寬單位和厘米的轉換

Excel中行高、列寬尺寸的換算一、先說明一下度量單位的相互換算關系&#xff1a;磅&#xff1a;指打印的字符的高度的度量單位。1 磅近似等于 1/72 英寸&#xff0c;或大約等于 1/28.35 厘米。英寸&#xff1a;1英寸近似等于 2.54 厘米。像素&#xff1a;與顯示解析度有關&…

使用Clion軟件實現基于國密SM2-SM3的SSL安全通信

參考鏈接 Ubuntu安裝GmSSL庫適用于ubuntu18和ubuntu20版本_MY CUP OF TEA的博客-CSDN博客CLion運行程序時添加命令行參數 即設置argv輸入參數_MY CUP OF TEA的博客-CSDN博客基于SM2證書實現SSL通信_MY CUP OF TEA的博客-CSDN博客基于Gmssl庫靜態編譯&#xff0c;實現服務端和客…

基于GmSSL實現server服務端和client客戶端之間SSL通信代碼(升級優化公開版)

參考鏈接 工程搭建介紹 Ubuntu安裝GmSSL庫適用于ubuntu18和ubuntu20版本_MY CUP OF TEA的博客-CSDN博客CLion運行程序時添加命令行參數 即設置argv輸入參數_MY CUP OF TEA的博客-CSDN博客基于SM2證書實現SSL通信_MY CUP OF TEA的博客-CSDN博客基于Gmssl庫靜態編譯&#xff0c…

easyui 表頭合并_JQuery EasyUI DataGrid動態合并(標題)單元) 一

JS&#xff1a;/*** EasyUI DataGrid根據字段動態合并單元格* param fldList 要合并table的id* param fldList 要合并的列,用逗號分隔(例如&#xff1a;"name,department,office");*/function MergeCells(tableID, fldList) {var Arr fldList.split(",");…

openssl 密碼套件相關內容(OID|密碼套件)

參考鏈接 SSL通信雙方如何判斷對方采用了國密 - Bigben - 博客園滑動驗證頁面 OpenSSL TLS1.2密碼套件推薦安全的TLS協議 | Hexo OID OID是由ISO/IEC、ITU-T國際標準化組織上世紀80年代聯合提出的標識機制&#xff0c;其野心很大&#xff0c;為任何類型的對象&#xff08;包…

墨刀可以導入文件嗎_墨刀和Sketch擦出的火花

墨刀開發的Sketch插件終于從內測中脫殼而出了&#xff0c;可以將Sketch中的Artboard直接導入墨刀中&#xff0c;然后進行交互操作(頁面跳轉)的鏈接設置。一時手癢&#xff0c;趕緊試了試&#xff0c;也把使用過程和感受分享給大家。(然而非要拖到周一才發)使用條件1)有Mac(因為…

Ubuntu配置gmssl和openssl,且均使用動態庫,使用時根據需要進行動態切換

前情提要 openssl和gmssl如果想要共存&#xff0c;只能一個是動態庫&#xff0c;一個是靜態庫配置openssl和gmssl無特定的編譯順序要求openssl3.x版本是未來趨勢&#xff0c;openssl1.1.x等版本只是適用于基礎軟件包&#xff0c;后期將會刪除配置文件 /etc/ld.so.conf文件只用…

thymeleaf動態選中select_一些LowPoly動態漸變效果實現

這篇文章根大家分享一些LowPoly動態效果的制作方法&#xff0c;由于使用的是uv采樣方式效率很高&#xff0c;手機也可以隨意使用&#xff0c;我們先來看一些效果的參考 本文將在Unity3D中還原這些效果,如果你學會后當然可以在你喜歡的引擎中實現~如果一篇太長有可能會分多篇&am…

使用Clion和gmssl動態庫實現服務器server和客戶端client之間的SSL通信

參考鏈接 Ubuntu配置gmssl和openssl&#xff0c;且均使用動態庫&#xff0c;使用時根據需要進行動態切換_MY CUP OF TEA的博客-CSDN博客 編譯gmssl動態庫并關閉openssl配置&#xff0c;開啟gmssl配置基于GmSSL實現server服務端和client客戶端之間SSL通信代碼&#xff08;升級…

shiro 攔截未登錄的ajax_Shiro是如何攔截未登錄請求的(二)

/*** 重寫父類獲取sessionID的方法,若請求為APP或者H5則從請求頭中取出token,若為PC端后臺則從cookie中獲取** param request* param response* return*/Overrideprotected Serializable getSessionId(ServletRequest request, ServletResponse response){if (!(request instan…

使用Clion和openssl動態庫實現服務器server和客戶端client之間的SSL通信

參考鏈接 使用Clion和gmssl動態庫實現服務器server和客戶端client之間的SSL通信_MY CUP OF TEA的博客-CSDN博客 服務端server CMakeLists.txt文件 cmake_minimum_required(VERSION 3.22)project(ssl_server) set(CMAKE_CXX_STANDARD 11)# 忽略警告 set(CMAKE_CXX_FLAGS &quo…

使用Clion和gmssl動態庫實現服務器server和客戶端client之間的SSL通信,測試指定密碼套件

參考鏈接 列出gmssl支持的國密算法TLS1.x密碼套件_liuqun69的博客-CSDN博客使用Clion和gmssl動態庫實現服務器server和客戶端client之間的SSL通信_MY CUP OF TEA的博客-CSDN博客 注意事項 GM/T 標準涵蓋 2 個協議&#xff1a;- SSL VPN 協議 (GM/T 0024-2014)- IPSec VPN 協議…

樣式緩存沒更新_差點沒認出來:Office 2019/365桌面新圖標來啦

微軟應該是從昨天晚上開始就向Microsoft Office 正式版通道推送新圖標(測試版早就推送了)&#xff0c;主要包括的是桌面文檔顯示圖標。目前微軟更新圖標的速度有些慢并且還有些混亂&#xff0c;因為這些圖標并不是同時更新的而存在分批分次推送情況。如下圖多數組件已經可以看到…

在Ubuntu上安裝Git

安裝步驟 首先&#xff0c;確認系統是否已安裝git&#xff0c;可以通過git指令進行查看&#xff0c;如果沒有&#xff0c;則輸入sudo apt-get install git命令進行安裝。 安全配置 安裝完成后進行git配置&#xff0c;輸入指令git config --global user.name "xxx"…

10kv線路負載率計算_電工必懂計算公式,你若不會,如何立足于電力行業?

一電力變壓器額定視在功率Sn200KVA&#xff0c;空載損耗Po0.4KW&#xff0c;額定電流時的短路損耗PK2.2KW,測得該變壓器輸出有功功率P2&#xff1d;140KW時&#xff0c;二次則功率因數20.8。求變壓器此時的負載率b 和工作效率。解&#xff1a;因P2bSn2100%bP2(Sn2)100%140(2000…

在基于 Ubuntu 的 Linux 發行版上安裝 Wireshark

參考鏈接 Ubuntu 上 Wireshark 的安裝與使用 - 知乎https://www.myfreax.com/how-to-add-apt-repository-in-ubuntu/ 前情提要 使用Ubuntu軟件中心或命令行apt或apt-get安裝軟件包時&#xff0c;這些軟件包是從一個或多個apt軟件存儲庫中下載的。 APT存儲庫是一個網絡服務器或…

使用wireshark抓包,驗證客戶端和服務端SSL通信時指定的算法套件

前情提要 使用Clion和gmssl動態庫實現服務器server和客戶端client之間的SSL通信&#xff0c;測試指定密碼套件_MY CUP OF TEA的博客-CSDN博客在基于 Ubuntu 的 Linux 發行版上安裝 Wireshark_MY CUP OF TEA的博客-CSDN博客本地搭建server和客戶端使用端口進行數據通信&#xf…

r語言隨機森林回歸預測_從零實現回歸隨機森林

一、前言回歸隨機森林作為一種機器學習和數據分析領域常用且有效的算法&#xff0c;對其原理和代碼實現過程的掌握是非常有必要的。為此&#xff0c;本文將著重介紹從零開始實現回歸隨機森林的過程&#xff0c;對于隨機森林和決策樹的相關理論原理將不做太深入的描述。本文的目…