gmssl總結(jié)



1、gmssl組成

分為加密和通信兩部分

2侵浸、加密

主要指的是sm2 sm3 sm4加密算法,以及相關(guān)的加密組件

3氢妈、通信

指的是gmtls

按照一個 GM/T 0024-2014規(guī)范實現(xiàn)的,采用雙證書精刷,簽名證書+加密證書

4魁巩、生成證書

可使用地址https://github.com/jntass/TASSL/tree/master/Tassl_demo/mk_tls_cert 下的SM2certgen.sh生成雙證書。

注意:生成請求時指定的摘要算法 在用請求生成證書時并不生效澳腹,需要重新指定,否則會使用默認的算法rsa-sha256

針對gmssl,簽名算法一定要是sm2sign-with-sm3

針對tassl,只要加密用的是sm2即可,sm2sign-with-sm3不是必須

5贯溅、兼容性

指的是gmssl對openssl的兼容性

ssl/tls下拄氯,僅支持有限的套件:

ECDHE-SM2-WITH-SMS4-SM3

ECDHE-SM2-WITH-SMS4-SHA256

不是完全兼容的

采用老的openssl證書,要指定tls版本為1或1.2才可以盗迟,或者直接使用TSLv1_2_method坤邪,使用TSL_method不可以,號稱的會自己檢測版本并沒有實現(xiàn)罚缕,貌似默認是使用1.1版本

6艇纺、雙證書

gmssl對雙證書和雙密鑰的設(shè)置

直接設(shè)置兩個sm2證書和密鑰就可以,沒有新增接口邮弹,都是代碼里自己適配:

keyusagedigitalSignature 類型的證書是簽名證書黔衡,否則是加密證書,密鑰呢,加密證書存在的時候是加密密鑰腌乡,否則是簽名密鑰

這個其實是有漏洞的盟劫,必須先設(shè)置簽名證書。与纽。然后才是加密證書

tassl是有的侣签,增加了一個設(shè)置加密密鑰的接口SSL_use_enc_PrivateKey,設(shè)置證書的接口也是代碼里適配的,證書類型需要keyusage(keyAgreementkeyEnciphermentdataEncipherment)

7急迂、版本

以上總結(jié)僅針對GmSSL最新版(v2.3.1)和tassl當前最新版(2018-09-17)

8影所、最新版的openssl已經(jīng)支持國密算法

僅僅支持國密的算法,通信還未支持

9僚碎、編程實現(xiàn)

server.c:

#include <stdio.h>

#include <string.h>

#include <openssl/evp.h>

#include <openssl/x509.h>

#include <openssl/ssl.h>

#include <openssl/pem.h>

#include <openssl/err.h>

#include <sys/socket.h>

#include <unistd.h>

#include <netinet/in.h>?

//#define CERTSERVER "/tmp/testopenssl/demoCA/cacert.pem"

//#define KEYSERVER "/tmp/testopenssl/demoCA/private/cakey.pem"

#define CERTSERVER "SS.pem"

#define KEYSERVER "SS.key.pem"

#define SM2_SERVER_ENC_CERT? ? "SE.pem"

#define SM2_SERVER_ENC_KEY? ? ? "SE.key.pem"

#define CHK_ERR(err, s) if((err) == -1) { perror(s); return -1; }else printf("%s? success!\n",s);

#define CHK_RV(rv, s) if((rv) != 1) { printf("%s error\n", s); return -1; }else printf("%s? success!\n",s);

#define CHK_NULL(x, s) if((x) == NULL) { printf("%s error\n", s); return -1; }else printf("%s? success!\n",s);

#define CHK_SSL(err, s) if((err) == -1) { ERR_print_errors_fp(stderr);? return -1;}else printf("%s? success!\n",s);

int main()

{

int rv, err;

SSL_CTX *ctx = NULL;

SSL_METHOD *meth = NULL;

int listen_sd;

int accept_sd;

struct sockaddr_in socketAddrServer;

struct sockaddr_in socketAddrClient;

socklen_t socketAddrClientLen;

SSL *ssl = NULL;

char buf[4096];

rv = SSL_library_init();

CHK_RV(rv, "SSL_library_init");

meth = (SSL_METHOD *)GMTLS_server_method();

ctx = SSL_CTX_new(meth);

CHK_NULL(ctx, "SSL_CTX_new");

rv = SSL_CTX_use_certificate_file(ctx, CERTSERVER, SSL_FILETYPE_PEM);

CHK_RV(rv, "SSL_CTX_use_certicificate_file");

rv = SSL_CTX_use_PrivateKey_file(ctx, KEYSERVER, SSL_FILETYPE_PEM);

CHK_RV(rv, "SSL_CTX_use_PrivateKey_file");

rv = SSL_CTX_check_private_key(ctx);

CHK_RV(rv, "SSL_CTX_check_private_key");

rv = SSL_CTX_use_certificate_file(ctx, SM2_SERVER_ENC_CERT, SSL_FILETYPE_PEM);

CHK_RV(rv, "SSL_CTX_use_certicificate_file2");

rv = SSL_CTX_use_PrivateKey_file(ctx, SM2_SERVER_ENC_KEY, SSL_FILETYPE_PEM);

CHK_RV(rv, "SSL_CTX_use_PrivateKey_file2");

rv = SSL_CTX_check_private_key(ctx);

CHK_RV(rv, "SSL_CTX_check_private_key2");

SSL_CTX_set_security_level(ctx, 0);

listen_sd = socket(AF_INET, SOCK_STREAM, 0);

CHK_ERR(listen_sd, "socket");

memset(&socketAddrServer, 0, sizeof(socketAddrServer));

socketAddrServer.sin_family = AF_INET;

socketAddrServer.sin_port = htons(8443);

socketAddrServer.sin_addr.s_addr = INADDR_ANY;

err = bind(listen_sd, (struct sockaddr *)&socketAddrServer, sizeof(socketAddrServer));

CHK_ERR(err, "bind");

err = listen(listen_sd, 5);

CHK_ERR(err, "listen");

socketAddrClientLen = sizeof(socketAddrClient);

accept_sd = accept(listen_sd, (struct sockaddr *)&socketAddrClient, &socketAddrClientLen);

CHK_ERR(accept_sd, "accept");

close(listen_sd);

printf("Connect from %lx, port %x\n", socketAddrClient.sin_addr.s_addr, socketAddrClient.sin_port);

ssl = SSL_new(ctx);

CHK_NULL(ssl, "SSL_new");

rv = SSL_set_fd(ssl, accept_sd);

CHK_RV(rv, "SSL_set_fd");

rv = SSL_accept(ssl);

CHK_RV(rv, "SSL_accpet");

/* Check for Client authentication error */

? if (SSL_get_verify_result(ssl) != X509_V_OK) {

? printf("SSL Client Authentication error\n");

? SSL_free(ssl);

? close(accept_sd);

? SSL_CTX_free(ctx);

? exit(0);

? }

/*Print out connection details*/

printf("SSL connection on socket %x,Version: %s, Cipher: %s\n",

accept_sd,

SSL_get_version(ssl),

SSL_get_cipher(ssl));

rv = SSL_read(ssl, buf, sizeof(buf) - 1);

CHK_SSL(rv, "SSL_read");

buf[rv] = '\0';

printf("Got %d chars :%s\n", rv, buf);

rv = SSL_write(ssl, "I accept your request", strlen("I accept your request"));

CHK_SSL(rv, "SSL_write");

close(accept_sd);

SSL_free(ssl);

SSL_CTX_free(ctx);

return 0;

}

client.c:

#include <stdio.h>

#include <string.h>

#include <openssl/evp.h>

#include <openssl/x509.h>

#include <openssl/ssl.h>

#include <openssl/pem.h>

#include <openssl/err.h>

#include <sys/socket.h>

#include <unistd.h>

#include <netinet/in.h>?

#include <arpa/inet.h>

#include <iostream>

#define SERVER_IP? ? ? "127.0.0.1"

#define SERVER_PORT? ? 8443

int main( int argc, char* argv[] ) {

? int ret;

? ////////////

? // 初始化 //

? ////////////

? SSL_CTX* ctx;

? SSL_METHOD *meth;

? OpenSSL_add_ssl_algorithms();

? SSL_load_error_strings();

? //meth = (SSL_METHOD *)TLS_client_method();

? meth = (SSL_METHOD *)GMTLS_client_method();

? ctx = SSL_CTX_new (meth);

? if (!ctx) {

? ? ERR_print_errors_fp(stderr);

? ? std::cout<<"SSL_CTX_new error."<<std::endl;

? ? return -1;

? }

? //SSL_CTX_set_cipher_list(ctx, "ECDHE-RSA-AES256-GCM-SHA384");

//? SSL_CTX_set_max_proto_version(ctx,TLS1_2_VERSION);

//? SSL_CTX_set_min_proto_version(ctx,TLS1_2_VERSION);

? ///////////////////////

? // 建立原始的TCP連接 //

? ///////////////////////

? int client_socket;

? struct sockaddr_in addr_server;

? client_socket = socket (AF_INET, SOCK_STREAM, 0);?

? if( client_socket == -1? ) {

? ? std::cout<<"socket error."<<std::endl;

? ? return -1;

? }

? memset (&addr_server, 0, sizeof(addr_server));

? addr_server.sin_family? ? ? ? ? = AF_INET;

? addr_server.sin_addr.s_addr = inet_addr(SERVER_IP);

? addr_server.sin_port? ? ? ? ? ? = htons (SERVER_PORT);

? ret = connect(client_socket, (struct sockaddr*) &addr_server, sizeof(addr_server));

? if( ret == -1? ) {

? ? std::cout<<"connect error."<<std::endl;

? ? return -1;

? }

? /////////////////////////////////////

? // TCP連接已經(jīng)建立猴娩,執(zhí)行Client SSL //

? /////////////////////////////////////

? SSL*? ? ssl;

? X509*? ? server_certificate;

? char*? ? str;

? ssl = SSL_new (ctx);? ? ? ? ? ? ? ? ? ? ? ?

? if( ssl == NULL ) {

? ? std::cout<<"SSL_new error."<<std::endl;

? ? return -1;

? }

? SSL_set_fd (ssl, client_socket);

? ret = SSL_connect (ssl);? ? ? ? ? ? ? ? ? ?

? if( ret == -1 ) {

? ? std::cout<<"SSL_connect error."<<std::endl;

ERR_print_errors_fp(stderr);

? ? return -1;

? }

? ? ERR_print_errors_fp(stderr);

? // 接下來的獲取密碼和獲取服務(wù)器端證書的兩部是可選的,不會影響數(shù)據(jù)交換

? // 獲取cipher

? std::cout<<"SSL connection using: "<<SSL_get_cipher(ssl)<<std::endl;

? // 獲取服務(wù)器端的證書

? server_certificate = SSL_get_peer_certificate (ssl);? ? ?

? if( server_certificate != NULL ) {

? ? std::cout<<"Server certificate:"<<std::endl;

? ? str = X509_NAME_oneline (X509_get_subject_name (server_certificate),0,0);

? ? if( str == NULL ) {

? ? ? std::cout<<"X509_NAME_oneline error."<<std::endl;

? ? } else {

? ? ? std::cout<<"subject: "<<str<<std::endl;

? ? ? OPENSSL_free (str);

? ? }

? ? str = X509_NAME_oneline (X509_get_issuer_name? (server_certificate),0,0);

? ? if( str == NULL ) {

? ? ? std::cout<<"X509_NAME_oneline error."<<std::endl;

? ? } else {

? ? ? std::cout<<"issuer: "<<str<<std::endl;

? ? ? OPENSSL_free (str);

? ? }

? ? X509_free (server_certificate);

? } else {

? ? std::cout<<"Server does not have certificate. we sould Esc!"<<std::endl;

? ? return -1;

? }

? ////////////////

? //? 數(shù)據(jù)交換? //

? ////////////////

? char? ? buf [4096];

? ret = SSL_write (ssl, "Hello World!", strlen("Hello World!"));?

? if( ret == -1 ) {

? ? std::cout<<"SSL_write error."<<std::endl;

? ? return -1;

? }

? ret = SSL_read (ssl, buf, sizeof(buf) - 1);?

? if( ret == -1 ) {

? ? std::cout<<"SSL_read error."<<std::endl;

? ? return -1;

? }

? buf[ret] = '\0';

? std::cout<<buf<<std::endl;

? SSL_shutdown(ssl);? /* send SSL/TLS close_notify */

? /////////////

? // Cleanup //

? /////////////

? close(client_socket);

? SSL_free (ssl);

? SSL_CTX_free (ctx);

? return 0;

}



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末勺阐,一起剝皮案震驚了整個濱河市卷中,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渊抽,老刑警劉巖蟆豫,帶你破解...
    沈念sama閱讀 222,000評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異懒闷,居然都是意外死亡无埃,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評論 3 399
  • 文/潘曉璐 我一進店門毛雇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來嫉称,“玉大人,你說我怎么就攤上這事灵疮≈模” “怎么了?”我有些...
    開封第一講書人閱讀 168,561評論 0 360
  • 文/不壞的土叔 我叫張陵震捣,是天一觀的道長荔棉。 經(jīng)常有香客問我闹炉,道長,這世上最難降的妖魔是什么润樱? 我笑而不...
    開封第一講書人閱讀 59,782評論 1 298
  • 正文 為了忘掉前任渣触,我火速辦了婚禮,結(jié)果婚禮上壹若,老公的妹妹穿的比我還像新娘嗅钻。我一直安慰自己,他們只是感情好店展,可當我...
    茶點故事閱讀 68,798評論 6 397
  • 文/花漫 我一把揭開白布养篓。 她就那樣靜靜地躺著,像睡著了一般赂蕴。 火紅的嫁衣襯著肌膚如雪柳弄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,394評論 1 310
  • 那天概说,我揣著相機與錄音碧注,去河邊找鬼。 笑死糖赔,一個胖子當著我的面吹牛应闯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挂捻,決...
    沈念sama閱讀 40,952評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼船万!你這毒婦竟也來了刻撒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,852評論 0 276
  • 序言:老撾萬榮一對情侶失蹤耿导,失蹤者是張志新(化名)和其女友劉穎声怔,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體舱呻,經(jīng)...
    沈念sama閱讀 46,409評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡醋火,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,483評論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了箱吕。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片芥驳。...
    茶點故事閱讀 40,615評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖茬高,靈堂內(nèi)的尸體忽然破棺而出兆旬,到底是詐尸還是另有隱情,我是刑警寧澤怎栽,帶...
    沈念sama閱讀 36,303評論 5 350
  • 正文 年R本政府宣布丽猬,位于F島的核電站宿饱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏脚祟。R本人自食惡果不足惜谬以,卻給世界環(huán)境...
    茶點故事閱讀 41,979評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望由桌。 院中可真熱鬧为黎,春花似錦、人聲如沸沥寥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,470評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽邑雅。三九已至片橡,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淮野,已是汗流浹背捧书。 一陣腳步聲響...
    開封第一講書人閱讀 33,571評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留骤星,地道東北人经瓷。 一個月前我還...
    沈念sama閱讀 49,041評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像洞难,于是被迫代替她去往敵國和親舆吮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,630評論 2 359