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

參考鏈接

  • 列出gmssl支持的國密算法TLS1.x密碼套件_liuqun69的博客-CSDN博客
  • 使用Clion和gmssl動態庫實現服務器server和客戶端client之間的SSL通信_MY CUP OF TEA的博客-CSDN博客

注意事項

GM/T 標準涵蓋 2 個協議:- SSL VPN 協議 (GM/T 0024-2014)- IPSec VPN 協議 (GM/T 0022-2014)GM/T 0024-2014 SSL VPN 協議與 IETF TLS 在以下方面有所不同:- 當前版本的 TLS 是 1.3 (0x0304),而 GM/T SSL 版本是 1.1 (0x0102)。- GM/T SSL 的握手協議與 TLS 握手不同。- 為 VPN 應用設計的 GM/T SSL 中有一個可選的不同記錄協議。- GM/T SSL 有 12 個密碼套件,其中一些密碼不提供前向保密。GM/T 0024-2014 密碼套件:```1. {0xe0,0x01} GMTLS_SM2DHE_SM2SIGN_WITH_SM1_SM32. {0xe0,0x03} GMTLS_SM2ENC_WITH_SM1_SM33. {0xe0,0x05} GMTLS_SM9DHE_SM9SIGN_WITH_SM1_SM34. {0xe0,0x07} GMTLS_SM9ENC_WITH_SM1_SM35. {0xe0,0x09} GMTLS_RSA_WITH_SM1_SM36. {0xe0,0x0a} GMTLS_RSA_WITH_SM1_SHA17. {0xe0,0x11} GMTLS_SM2DHE_SM2SIGN_WITH_SMS4_SM38. {0xe0,0x13} GMTLS_SM2ENC_WITH_SMS4_SM39. {0xe0,0x15} GMTLS_SM9DHE_SM9SIGN_WITH_SMS4_SM3
10. {0xe0,0x17} GMTLS_SM9ENC_WITH_SMS4_SM3
11. {0xe0,0x19} GMTLS_RSA_WITH_SMS4_SM3
12. {0xe0,0x1a} GMTLS_RSA_WITH_SMS4_SHA1
  • ?雖然gmssl的源碼文件夾里面的 README.md 明確指出,其支持國密算法12種算法套件
  • 但是,使用命令?gmssl ciphers -V 列舉其支持的算法TLS1.x密碼套件,卻根本不涵蓋上述7和8
chy-cpabe@ubuntu:~/ssl_server_client/ca$ gmssl ciphers -V0xC0,0x2C - ECDHE-ECDSA-AES256-GCM-SHA384  TLSv1.2    Kx=ECDH     Au=ECDSA  Enc=AESGCM(256)             Mac=AEAD0xC0,0x30 - ECDHE-RSA-AES256-GCM-SHA384    TLSv1.2    Kx=ECDH     Au=RSA    Enc=AESGCM(256)             Mac=AEAD0x00,0x9F - DHE-RSA-AES256-GCM-SHA384      TLSv1.2    Kx=DH       Au=RSA    Enc=AESGCM(256)             Mac=AEAD0xCC,0xA9 - ECDHE-ECDSA-CHACHA20-POLY1305  TLSv1.2    Kx=ECDH     Au=ECDSA  Enc=CHACHA20/POLY1305(256)  Mac=AEAD0xCC,0xA8 - ECDHE-RSA-CHACHA20-POLY1305    TLSv1.2    Kx=ECDH     Au=RSA    Enc=CHACHA20/POLY1305(256)  Mac=AEAD0xCC,0xAA - DHE-RSA-CHACHA20-POLY1305      TLSv1.2    Kx=DH       Au=RSA    Enc=CHACHA20/POLY1305(256)  Mac=AEAD0xC0,0x2B - ECDHE-ECDSA-AES128-GCM-SHA256  TLSv1.2    Kx=ECDH     Au=ECDSA  Enc=AESGCM(128)             Mac=AEAD0xC0,0x2F - ECDHE-RSA-AES128-GCM-SHA256    TLSv1.2    Kx=ECDH     Au=RSA    Enc=AESGCM(128)             Mac=AEAD0x00,0x9E - DHE-RSA-AES128-GCM-SHA256      TLSv1.2    Kx=DH       Au=RSA    Enc=AESGCM(128)             Mac=AEAD0xE1,0x07 - ECDHE-SM2-WITH-SMS4-GCM-SM3    TLSv1.2    Kx=ECDH     Au=SM2    Enc=SMS4GCM(128)            Mac=AEAD0xC0,0x24 - ECDHE-ECDSA-AES256-SHA384      TLSv1.2    Kx=ECDH     Au=ECDSA  Enc=AES(256)                Mac=SHA3840xC0,0x28 - ECDHE-RSA-AES256-SHA384        TLSv1.2    Kx=ECDH     Au=RSA    Enc=AES(256)                Mac=SHA3840x00,0x6B - DHE-RSA-AES256-SHA256          TLSv1.2    Kx=DH       Au=RSA    Enc=AES(256)                Mac=SHA2560xC0,0x23 - ECDHE-ECDSA-AES128-SHA256      TLSv1.2    Kx=ECDH     Au=ECDSA  Enc=AES(128)                Mac=SHA2560xC0,0x27 - ECDHE-RSA-AES128-SHA256        TLSv1.2    Kx=ECDH     Au=RSA    Enc=AES(128)                Mac=SHA2560x00,0x67 - DHE-RSA-AES128-SHA256          TLSv1.2    Kx=DH       Au=RSA    Enc=AES(128)                Mac=SHA2560xE1,0x02 - ECDHE-SM2-WITH-SMS4-SM3        TLSv1.2    Kx=ECDH     Au=SM2    Enc=SMS4(128)               Mac=SM3 0xC0,0x0A - ECDHE-ECDSA-AES256-SHA         SSLv3      Kx=ECDH     Au=ECDSA  Enc=AES(256)                Mac=SHA10xC0,0x14 - ECDHE-RSA-AES256-SHA           SSLv3      Kx=ECDH     Au=RSA    Enc=AES(256)                Mac=SHA10x00,0x39 - DHE-RSA-AES256-SHA             SSLv3      Kx=DH       Au=RSA    Enc=AES(256)                Mac=SHA10xC0,0x09 - ECDHE-ECDSA-AES128-SHA         SSLv3      Kx=ECDH     Au=ECDSA  Enc=AES(128)                Mac=SHA10xC0,0x13 - ECDHE-RSA-AES128-SHA           SSLv3      Kx=ECDH     Au=RSA    Enc=AES(128)                Mac=SHA10x00,0x33 - DHE-RSA-AES128-SHA             SSLv3      Kx=DH       Au=RSA    Enc=AES(128)                Mac=SHA10x00,0xAD - RSA-PSK-AES256-GCM-SHA384      TLSv1.2    Kx=RSAPSK   Au=RSA    Enc=AESGCM(256)             Mac=AEAD0x00,0xAB - DHE-PSK-AES256-GCM-SHA384      TLSv1.2    Kx=DHEPSK   Au=PSK    Enc=AESGCM(256)             Mac=AEAD0xCC,0xAE - RSA-PSK-CHACHA20-POLY1305      TLSv1.2    Kx=RSAPSK   Au=RSA    Enc=CHACHA20/POLY1305(256)  Mac=AEAD0xCC,0xAD - DHE-PSK-CHACHA20-POLY1305      TLSv1.2    Kx=DHEPSK   Au=PSK    Enc=CHACHA20/POLY1305(256)  Mac=AEAD0xCC,0xAC - ECDHE-PSK-CHACHA20-POLY1305    TLSv1.2    Kx=ECDHEPSK Au=PSK    Enc=CHACHA20/POLY1305(256)  Mac=AEAD0x00,0x9D - AES256-GCM-SHA384              TLSv1.2    Kx=RSA      Au=RSA    Enc=AESGCM(256)             Mac=AEAD0x00,0xA9 - PSK-AES256-GCM-SHA384          TLSv1.2    Kx=PSK      Au=PSK    Enc=AESGCM(256)             Mac=AEAD0xCC,0xAB - PSK-CHACHA20-POLY1305          TLSv1.2    Kx=PSK      Au=PSK    Enc=CHACHA20/POLY1305(256)  Mac=AEAD0x00,0xAC - RSA-PSK-AES128-GCM-SHA256      TLSv1.2    Kx=RSAPSK   Au=RSA    Enc=AESGCM(128)             Mac=AEAD0x00,0xAA - DHE-PSK-AES128-GCM-SHA256      TLSv1.2    Kx=DHEPSK   Au=PSK    Enc=AESGCM(128)             Mac=AEAD0x00,0x9C - AES128-GCM-SHA256              TLSv1.2    Kx=RSA      Au=RSA    Enc=AESGCM(128)             Mac=AEAD0x00,0xA8 - PSK-AES128-GCM-SHA256          TLSv1.2    Kx=PSK      Au=PSK    Enc=AESGCM(128)             Mac=AEAD0x00,0x3D - AES256-SHA256                  TLSv1.2    Kx=RSA      Au=RSA    Enc=AES(256)                Mac=SHA2560x00,0x3C - AES128-SHA256                  TLSv1.2    Kx=RSA      Au=RSA    Enc=AES(128)                Mac=SHA2560xC0,0x38 - ECDHE-PSK-AES256-CBC-SHA384    TLSv1      Kx=ECDHEPSK Au=PSK    Enc=AES(256)                Mac=SHA3840xC0,0x36 - ECDHE-PSK-AES256-CBC-SHA       SSLv3      Kx=ECDHEPSK Au=PSK    Enc=AES(256)                Mac=SHA10xC0,0x21 - SRP-RSA-AES-256-CBC-SHA        SSLv3      Kx=SRP      Au=RSA    Enc=AES(256)                Mac=SHA10xC0,0x20 - SRP-AES-256-CBC-SHA            SSLv3      Kx=SRP      Au=SRP    Enc=AES(256)                Mac=SHA10x00,0xB7 - RSA-PSK-AES256-CBC-SHA384      TLSv1      Kx=RSAPSK   Au=RSA    Enc=AES(256)                Mac=SHA3840x00,0xB3 - DHE-PSK-AES256-CBC-SHA384      TLSv1      Kx=DHEPSK   Au=PSK    Enc=AES(256)                Mac=SHA3840x00,0x95 - RSA-PSK-AES256-CBC-SHA         SSLv3      Kx=RSAPSK   Au=RSA    Enc=AES(256)                Mac=SHA10x00,0x91 - DHE-PSK-AES256-CBC-SHA         SSLv3      Kx=DHEPSK   Au=PSK    Enc=AES(256)                Mac=SHA10x00,0x35 - AES256-SHA                     SSLv3      Kx=RSA      Au=RSA    Enc=AES(256)                Mac=SHA10x00,0xAF - PSK-AES256-CBC-SHA384          TLSv1      Kx=PSK      Au=PSK    Enc=AES(256)                Mac=SHA3840x00,0x8D - PSK-AES256-CBC-SHA             SSLv3      Kx=PSK      Au=PSK    Enc=AES(256)                Mac=SHA10xC0,0x37 - ECDHE-PSK-AES128-CBC-SHA256    TLSv1      Kx=ECDHEPSK Au=PSK    Enc=AES(128)                Mac=SHA2560xC0,0x35 - ECDHE-PSK-AES128-CBC-SHA       SSLv3      Kx=ECDHEPSK Au=PSK    Enc=AES(128)                Mac=SHA10xC0,0x1E - SRP-RSA-AES-128-CBC-SHA        SSLv3      Kx=SRP      Au=RSA    Enc=AES(128)                Mac=SHA10xC0,0x1D - SRP-AES-128-CBC-SHA            SSLv3      Kx=SRP      Au=SRP    Enc=AES(128)                Mac=SHA10x00,0xB6 - RSA-PSK-AES128-CBC-SHA256      TLSv1      Kx=RSAPSK   Au=RSA    Enc=AES(128)                Mac=SHA2560x00,0xB2 - DHE-PSK-AES128-CBC-SHA256      TLSv1      Kx=DHEPSK   Au=PSK    Enc=AES(128)                Mac=SHA2560x00,0x94 - RSA-PSK-AES128-CBC-SHA         SSLv3      Kx=RSAPSK   Au=RSA    Enc=AES(128)                Mac=SHA10x00,0x90 - DHE-PSK-AES128-CBC-SHA         SSLv3      Kx=DHEPSK   Au=PSK    Enc=AES(128)                Mac=SHA10xF1,0x20 - ECDHE-PSK-WITH-SMS4-CBC-SM3    TLSv1      Kx=ECDHEPSK Au=PSK    Enc=SMS4(128)               Mac=SM3 0xE0,0x17 - SM9-WITH-SMS4-SM3              GMTLSv1.1  Kx=SM9      Au=SM9    Enc=SMS4(128)               Mac=SM3 0xE0,0x15 - SM9DHE-WITH-SMS4-SM3           GMTLSv1.1  Kx=SM9DHE   Au=SM9    Enc=SMS4(128)               Mac=SM3 0xE0,0x13 - SM2-WITH-SMS4-SM3              GMTLSv1.1  Kx=SM2      Au=SM2    Enc=SMS4(128)               Mac=SM3 0xE0,0x11 - SM2DHE-WITH-SMS4-SM3           GMTLSv1.1  Kx=SM2DHE   Au=SM2    Enc=SMS4(128)               Mac=SM3 0x00,0x2F - AES128-SHA                     SSLv3      Kx=RSA      Au=RSA    Enc=AES(128)                Mac=SHA10xE0,0x1A - RSA-WITH-SMS4-SHA1             GMTLSv1.1  Kx=RSA      Au=RSA    Enc=SMS4(128)               Mac=SHA10xE0,0x19 - RSA-WITH-SMS4-SM3              GMTLSv1.1  Kx=RSA      Au=RSA    Enc=SMS4(128)               Mac=SM3 0x00,0xAE - PSK-AES128-CBC-SHA256          TLSv1      Kx=PSK      Au=PSK    Enc=AES(128)                Mac=SHA2560x00,0x8C - PSK-AES128-CBC-SHA             SSLv3      Kx=PSK      Au=PSK    Enc=AES(128)                Mac=SHA10xF1,0x01 - PSK-WITH-SMS4-CBC-SM3          SSLv3      Kx=PSK      Au=PSK    Enc=SMS4(128)               Mac=SM3 
  • 添加代碼如下
  • 原因
    • ca、服務器和客戶端的證書 均為國密證書
    • ? ? ? ? /* 申請SSL會話環境 */ ? ? ? ? if( nullptr==(ctx=SSL_CTX_new(TLSv1_2_method())) ) ? ?//使用SSL_CTX_new()創建會話環境,建立連接時要使用協議由TLS_client_method()來定,服務器由對應的TLS_server_method()來定。如果這一步出錯,需要查看錯誤棧來查看原因;指定了TLSv1_2_method模式
        //指定密碼算法套件// gmssl ciphers -V 明確支持SSL_CTX_set_cipher_list(ctx,"ECDHE-SM2-WITH-SMS4-GCM-SM3");// SM2-XXX
//        SSL_CTX_set_cipher_list(ctx,"GMTLS_SM2DHE_SM2SIGN_WITH_SMS4_SM3"); //{0xe0,0x11}
//        SSL_CTX_set_cipher_list(ctx,"GMTLS_SM2ENC_WITH_SMS4_SM3"); //{0xe0,0x13}
  • ?ECDHE-SM2-WITH-SMS4-SM3 是默認的算法,且是gmssl自我實現的算法,并未得到官方認證
GmSSL supports the standard TLS 1.2 protocol with SM2/SM3/SM4 ciphersuites and the GM/T SSL VPN protocol and ciphersuites. Currently the following ciphersuites are supported:```
ECDHE-SM2-WITH-SMS4-SM3
ECDHE-SM2-WITH-SMS4-SHA256
GmSSL 支持帶有 SM2/SM3/SM4 密碼套件的標準 TLS 1.2 協議以及 GM/T SSL VPN 協議和密碼套件。 目前支持以下密碼套件:```
ECDHE-SM2-WITH-SMS4-SM3
ECDHE-SM2-WITH-SMS4-SHA256

?代碼

服務端 server

#include <cstdio>
#include <cstdlib>
#include <cerrno>
#include <cstring>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>#define MAXBUF 1500void 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 != nullptr) {printf("數字證書信息:\n");line = X509_NAME_oneline(X509_get_subject_name(cert), nullptr, 0);printf("證書: %s\n", line);free(line);line = X509_NAME_oneline(X509_get_issuer_name(cert), nullptr, 0);printf("頒發者: %s\n", line);free(line);X509_free(cert);} elseprintf("無證書信息!\n");
}int main(int argc, char **argv) {int listen_fd = -1; /* TCP監聽套接字 */int accept_fd = -1; /* 已連接TCP套接字 */struct sockaddr_in server_addr, client_addr;bzero(&server_addr, sizeof(server_addr));SSL_CTX *ctx = nullptr; /* SSL會話環境 */SSL *ssl = nullptr; /* SSL安全套接字 */socklen_t len;char buf[MAXBUF]={0};  /* 服務器接收數據buffer */if( 3!=argc ){printf("argcment wrong:ip port\n");}SSL_library_init(); /* SSL 庫初始化 */SSLeay_add_ssl_algorithms();OpenSSL_add_all_algorithms();  /* 載入所有 SSL 算法 */SSL_load_error_strings(); /* 載入所有 SSL 錯誤消息 */
//    ERR_load_BIO_strings();//TCP服務器:創建、綁定、監聽if ((listen_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {perror("socket create wrong\n");exit(1);} elseprintf("socket created\n");server_addr.sin_family = PF_INET;server_addr.sin_port = htons(atoi(argv[2]));server_addr.sin_addr.s_addr = inet_addr(argv[1]);;if (bind(listen_fd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr))== -1) {perror("bind wrong\n");exit(1);} elseprintf("binded success\n");int lisnum = 2;do{//使用SSL_CTX_new()創建會話環境,建立連接時要使用協議由TLS_server_method()來定。如果這一步出錯,需要查看錯誤棧來查看原因if(nullptr == (ctx = SSL_CTX_new( TLSv1_2_method())))		//using sm3, TLSv1_2_method{ERR_print_errors_fp(stdout);break;}
//        SSL_CTX_set_security_level(ctx,0);//指定密碼算法套件// gmssl ciphers -V 明確支持SSL_CTX_set_cipher_list(ctx,"ECDHE-SM2-WITH-SMS4-GCM-SM3");// SM2-XXX
//        SSL_CTX_set_cipher_list(ctx,"GMTLS_SM2DHE_SM2SIGN_WITH_SMS4_SM3"); //{0xe0,0x11}
//        SSL_CTX_set_cipher_list(ctx,"GMTLS_SM2ENC_WITH_SMS4_SM3"); //{0xe0,0x13}// 雙向驗證// 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, nullptr);// 設置信任根證書if(SSL_CTX_load_verify_locations(ctx, "/home/chy-cpabe/CLionProjects/learn_GmSSL_server/pem/CaCert.pem", nullptr) != 1)
//        if(SSL_CTX_load_verify_locations(ctx, "/home/chy-cpabe/ssl_server_client.openssl_bak/ca/ca.crt", nullptr) != 1){printf("SSL_CTX_load_verify_locations error\n");ERR_print_errors_fp(stdout);break;}/* 載入用戶的數字證書, 此證書用來發送給客戶端。 證書里包含有公鑰 */if( 0>=SSL_CTX_use_certificate_file(ctx, "/home/chy-cpabe/CLionProjects/learn_GmSSL_server/pem/HuiguanCert.pem", SSL_FILETYPE_PEM/*SSL_FILETYPE_ASN1*/) ) /* 為SSL會話加載用戶證書 */
//        if( 0>=SSL_CTX_use_certificate_file(ctx, "/home/chy-cpabe/ssl_server_client.openssl_bak/server/pem/server.crt", SSL_FILETYPE_PEM/*SSL_FILETYPE_ASN1*/) ) /* 為SSL會話加載用戶證書 */{ERR_print_errors_fp(stdout);break;}/* 載入用戶私鑰 */if( 0>=SSL_CTX_use_PrivateKey_file(ctx, "/home/chy-cpabe/CLionProjects/learn_GmSSL_server/pem/HuiguanKey.pem", SSL_FILETYPE_PEM/*SSL_FILETYPE_ASN1*/) ) /* 為SSL會話加載用戶私鑰 */
//        if( 0>=SSL_CTX_use_PrivateKey_file(ctx, "/home/chy-cpabe/ssl_server_client.openssl_bak/server/pem/server_rsa_private.pem.unsecure", SSL_FILETYPE_PEM/*SSL_FILETYPE_ASN1*/) ) /* 為SSL會話加載用戶私鑰 */{ERR_print_errors_fp(stdout);break;}/* 檢查用戶私鑰是否正確 */if(!SSL_CTX_check_private_key(ctx))                                 										 /* 驗證私鑰和證書是否相符 */{ERR_print_errors_fp(stdout);break;}if (listen(listen_fd, lisnum) == -1) {perror("listen wrong\n");exit(1);} elseprintf("begin listen\n");len = sizeof(struct sockaddr);/* 等待客戶端連上來 */if ((accept_fd = accept(listen_fd, (struct sockaddr *) &client_addr, &len))== -1) {perror("accept wrong\n");exit(errno);} else{printf("server: got connection from %s, port %d, socket %d\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port),accept_fd);}ssl = SSL_new(ctx); /* 基于 ctx 產生一個新的 SSL */SSL_set_fd(ssl, accept_fd); /* 將連接用戶的 socket 加入到 SSL *//* 建立 SSL 連接 */if (SSL_accept(ssl) == -1) {perror("accept wrong\n");SSL_shutdown(ssl);SSL_free(ssl);ssl= nullptr;close(accept_fd);accept_fd=-1;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);ssl = nullptr;/* 關閉 socket */close(accept_fd);accept_fd = -1;}while(1);/* 關閉監聽的 socket */close(listen_fd);listen_fd = -1;/* 釋放 CTX */SSL_CTX_free(ctx);ctx = nullptr;return 0;
}

客戶端 client

#include <cstdio>
#include <cstring>
#include <cerrno>
#include <sys/socket.h>
#include <cstdlib>
#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 != nullptr) {printf("數字證書信息:\n");line = X509_NAME_oneline(X509_get_subject_name(cert), nullptr, 0);printf("證書: %s\n", line);free(line);line = X509_NAME_oneline(X509_get_issuer_name(cert), nullptr, 0);printf("頒發者: %s\n", line);free(line);X509_free(cert);} elseprintf("無證書信息!\n");
}static void PrintData(char *p, char *buf,int len,char *filename)
{char *name=p;printf("%s[%d]:\n",p,len);for (p=buf; p && p++-buf<len;)printf("%02x%c",(unsigned char)p[-1],(!((p-buf)%16) || p-buf==len)?'\n':' ');
//	if (filename) FileWrite(name,buf,len,filename);
}int main(int argc, char **argv)
{int sock_fd = -1;            /* TCP套接字    */int len = 0;                 /* SSL會話環境 */SSL *ssl = nullptr;          /* SSL安全套接字 */struct sockaddr_in ser_addr; /* 服務器地址 */bzero(&ser_addr, sizeof(ser_addr));SSL_CTX *ctx = nullptr;char buffer[MAXBUF + 1];if( argc != 3 ){printf("argcment wrong:ip port content\n");exit(0);}/* SSL 庫初始化,參看 ssl-server.c 代碼 */SSL_library_init();SSLeay_add_ssl_algorithms();OpenSSL_add_all_algorithms();SSL_load_error_strings();
//    ERR_load_BIO_strings();do{/* 申請SSL會話環境 */if( nullptr==(ctx=SSL_CTX_new(TLSv1_2_method())) )    //使用SSL_CTX_new()創建會話環境,建立連接時要使用協議由TLS_client_method()來定,服務器由對應的TLS_server_method()來定。如果這一步出錯,需要查看錯誤棧來查看原因{ERR_print_errors_fp(stdout);break;}//指定密碼算法套件// gmssl ciphers -V 明確支持SSL_CTX_set_cipher_list(ctx,"ECDHE-SM2-WITH-SMS4-GCM-SM3");// SM2-XXX
//        SSL_CTX_set_cipher_list(ctx,"GMTLS_SM2DHE_SM2SIGN_WITH_SMS4_SM3"); //{0xe0,0x11}
//        SSL_CTX_set_cipher_list(ctx,"GMTLS_SM2ENC_WITH_SMS4_SM3"); //{0xe0,0x13}// 雙向驗證// 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, nullptr);// 設置信任根證書if (SSL_CTX_load_verify_locations(ctx, "/home/chy-cpabe/CLionProjects/learn_GmSSL_server/pem/CaCert.pem",nullptr)<=0)
//        if(SSL_CTX_load_verify_locations(ctx, "/home/chy-cpabe/ssl_server_client.openssl_bak/ca/ca.crt", nullptr) != 1){ERR_print_errors_fp(stdout);exit(1);}/* 載入用戶的數字證書, 此證書用來發送給客戶端。 證書里包含有公鑰 */if (SSL_CTX_use_certificate_file(ctx, "/home/chy-cpabe/CLionProjects/ssl_client/src/pem/TerminalCert.pem", SSL_FILETYPE_PEM) <= 0)
//        if (SSL_CTX_use_certificate_file(ctx, "/home/chy-cpabe/ssl_server_client.openssl_bak/client/pem/client.crt", SSL_FILETYPE_PEM) <= 0){ERR_print_errors_fp(stdout);exit(1);}/* 載入用戶私鑰 */if (SSL_CTX_use_PrivateKey_file(ctx, "/home/chy-cpabe/CLionProjects/ssl_client/src/pem/TerminalKey.pem", SSL_FILETYPE_PEM) <= 0)
//        if (SSL_CTX_use_PrivateKey_file(ctx, "/home/chy-cpabe/ssl_server_client.openssl_bak/client/pem/client_rsa_private.pem.unsecure", 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);}//https://www.openssl.org/docs/man1.0.2/man3/SSL_CTX_set_mode.htmlSSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);/* 創建一個 socket 用于 tcp 通信 */if(-1==(sock_fd=socket(AF_INET, SOCK_STREAM, 0)) ){printf("creat socket wrong\n");break;}printf("socket created\n");/* 初始化服務器端(對方)的地址和端口信息 */ser_addr.sin_family = AF_INET;ser_addr.sin_port = htons(atoi(argv[2]));ser_addr.sin_addr.s_addr = inet_addr(argv[1]);//將網絡地址轉成網絡二進制的數字//http://c.biancheng.net/cpp/html/362.html//另外一種寫法
/*		if (inet_aton(argv[1], (struct in_addr *) &ser_addr.sin_addr.s_addr) == 0) {perror(argv[1]);exit(errno);}
*/printf("address created\n");//建立連接if( -1==(connect(sock_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr))) ){printf("connect wrong\n");break;}printf("server connected\n");/* 基于 ctx 產生一個新的 SSL */ssl = SSL_new(ctx);SSL_set_fd(ssl, sock_fd);/* 建立 SSL 連接 */if (SSL_connect(ssl) == -1)ERR_print_errors_fp(stderr);else {printf("The relevant information is as follows:\n");printf("-->ssl version %s\n",SSL_get_version(ssl));printf("-->ssleay version %s\n",SSLeay_version(0));printf("-->Connected with %s encryption\n", SSL_get_cipher(ssl));ShowCerts(ssl);}//導出key和saltunsigned char buf[16];int err = -1;err = SSL_export_keying_material(ssl, buf, 16, nullptr,0, nullptr, 0, 1);if(err != 1){printf("err=%d\n",err);}else{PrintData("SSL_export_keying_material", (char*)buf, 16, nullptr);}/* 接收對方發過來的消息,最多接收 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 連接 */SSL_shutdown(ssl);/* 釋放 SSL */SSL_free(ssl);ssl = nullptr;}while(0);/* 關閉socket */close(sock_fd);sock_fd = -1;/* 釋放 CTX */SSL_CTX_free(ctx);ctx = nullptr;return 0;
}

測試

?

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

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

相關文章

樣式緩存沒更新_差點沒認出來: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;對于隨機森林和決策樹的相關理論原理將不做太深入的描述。本文的目…

openssl編程-基礎知識-回調函數

參考內容 OpenSSL編程 趙春平 回調函數 回調函數就是一個通過函數指針調用的函數。如果你把函數的指針&#xff08;地址&#xff09;作為參數傳遞給另一個函數&#xff0c;當這個指針被用來調用其所指向的函數時&#xff0c;我們就說這是回調函數把一段可執行的代碼像參數傳遞…

hive插件 ranger_Apache Ranger及Hive權限控制

一、Ranger概述1.Ranger簡介Apache Ranger提供一個集中式安全管理框架, 并解決授權和審計。它可以對Hadoop生態的組件如HDFS、Yarn、Hive、Hbase等進行細粒度的數據訪問控制。通過操作Ranger控制臺,管理員可以輕松的通過配置策略來控制用戶訪問權限。本文章介紹Ranger與Hive集成…

openssl編程-基礎知識-OpenSSL簡介

參考鏈接 在ubuntu環境下執行openssl編譯和安裝_MY CUP OF TEA的博客-CSDN博客_openssl ubuntuOpenSSL編程 趙春平 OpenSSL 簡介 它提供的主要功能有&#xff1a;SSL協議實現(包括SSLv2、SSLv3和TLSv1)、大量軟算法(對稱/非對稱/摘要)、大數運算、非對稱算法密鑰生成、ASN.1編…

linux修改文件句柄數生效_linux系統層面調優和常見的面試題

linux系統層面調優和常見的面試題?mp.weixin.qq.com無論對Spark集群&#xff0c;還是Hadoop集群等大數據相關的集群進行調優&#xff0c;對linux系統層面的調優都是必不可少的&#xff0c;這里主要介紹3種常用的調優&#xff1a;1.linux文件句柄linux在整個系統層面和單個進程…

openssl編程-基礎知識-OpenSSL堆棧

堆棧介紹 堆棧是一種先進后出的數據結構openssl 大量采用堆棧來存放數據。它實現了一 個通用的堆棧&#xff0c;可以方便的存儲任意數據它實現了許多基本的堆棧操作&#xff0c;主要有&#xff1a;堆棧拷貝(sk_dup)、構建新堆棧&#xff08;sk_new_null&#xff0c;sk_new&…

小米用戶畫像_企鵝智庫:高學歷用蘋果中老年用華為 男性用小米女性用OV

不同手機品牌都有著自己不同的定位人群&#xff0c;在國內市場目前幾大非常有名的手機品牌分別被三星、蘋果、華為、小米、OV占據&#xff0c;而這些手機品牌的主要購買人群到底是什么樣的呢&#xff1f;企鵝智庫近日發布了一份手機消費者的調研報告&#xff0c;并且根據消費者…

國密gmtls協議-雙證書體系的服務端和客戶端通信代碼

內容介紹 國密的雙證書體系&#xff0c;將證書按照使用目的的不同劃分為加密證書和簽名證書兩種&#xff0c;也就是兩對公私鑰&#xff0c;二者本質一致&#xff0c;均為SM2密鑰對&#xff0c;區別僅體現在用法國密CA體系中&#xff0c;加密密鑰對由CA產生&#xff0c;簽名密鑰…

jwt 私鑰_什么是 JSON Web Token(JWT)

有關本文檔的快速鏈接&#xff0c;請參考頁面提示。什么是 JSON Web Token(JWT)?JSON Web Token (JWT) 作為一個開放的標準 (RFC 7519) 定義了一種簡潔自包含的方法用于通信雙方之間以 JSON 對象的形式安全的傳遞信息。因為有數字簽名&#xff0c;所以這些通信的信息能夠被校驗…

server和client之間進行Socket通信,進行數據切片

參考鏈接 send函數和recv函數 – gudakos memo 注意事項 代碼很low&#xff0c;主要看封裝的Send函數所體現的切片思想即可 server代碼 //udp服務端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include …

天線下傾角示意圖_常用天線和無源器件技術參數匯總

原標題&#xff1a;常用天線和無源器件技術參數匯總一、天線原理天線的定義&#xff1a; 能夠有效地向空間某特定方向輻射電磁波或能夠有效的接收空間某特定方向來的電磁波的裝置。天線的功能&#xff1a; 能量轉換-導行波和自由空間波的轉換; 定向輻射(接收)-具有一定的方向性…

制作作品圖片_不懂人文后期制作流程?來,大師手把手教你

制作前1、處理一張照片思路決定步驟 想要了解學習的老師可以私聊小編fzhdyx222制作后2、2020年最新Camera Raw局部影調和色調的控制想要了解學習的老師可以私聊小編fzhdyx222制作前3、2020年最新Camera Raw基礎工具細節性運用想要了解學習的老師可以私聊小編fzhdyx222制作后4、…

xlsx文件打開亂碼_Excel 2016 雙擊無法打開xlsx文件怎么辦?

最近我重裝了系統(Win10Office2016)&#xff0c;然后發現了一個奇怪的bug&#xff1a;雙擊xlsx文件&#xff0c;只能打開Excel窗口&#xff0c;但是打不開這個文件&#xff0c;有時候再次雙擊就能打開了&#xff0c;但有時再次雙擊也不管用&#xff0c;需要在Excel的菜單中點“…

gmssl使用雙證書雙向認證的gmtl協議報錯crypto/sm2/sm2_sign.c 510: sm2_do_verifySSL3 alert write:fatal:decrypt error

報錯內容 crypto/sm2/sm2_sign.c 510: sm2_do_verify SSL3 alert write:fatal:decrypt error SSL_accept:error in error ERROR 140655864152064:error:1417B07B:SSL routines:tls_process_cert_verify:bad signature:ssl/statem/statem_srvr.c:2941: 相關內容 版本&#xf…

糾偏的意思_承壓能力和糾偏能力,決定成長的高度

承壓能力&#xff0c;包含抗壓能力、抵御能力&#xff0c;擔當能力&#xff0c;分解能力&#xff0c;消化能力&#xff0c;釋放能力&#xff0c;等一系列的精神要素&#xff0c;是一個人生存生活工作中一項重要的素質。有的人&#xff0c;承壓能力很強&#xff0c;無論經受什么…