日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

netty实现gmssl_gmssl国密总结

發布時間:2023/12/10 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 netty实现gmssl_gmssl国密总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1、gmssl組成

分為加密和通信兩部分

2、加密

主要指的是sm2 sm3 sm4加密算法,以及相關的加密組件

3、通信

指的是gmtls

按照一個 GM/T 0024-2014規范實現的,采用雙證書,簽名證書+加密證書

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不可以,號稱的會自己檢測版本并沒有實現,貌似默認是使用1.1版本

6、雙證書

gmssl對雙證書和雙密鑰的設置

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

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

這個其實是有漏洞的,必須先設置簽名證書。。然后才是加密證書

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

7、版本

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

8、最新版的openssl已經支持國密算法

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

9、編程實現

server.c:

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

//#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

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#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<

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<

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<

return -1;

}

/

// TCP連接已經建立,執行Client SSL //

/

SSL*? ? ssl;

X509*? ? server_certificate;

char*? ? str;

ssl = SSL_new (ctx);

if( ssl == NULL ) {

std::cout<

return -1;

}

SSL_set_fd (ssl, client_socket);

ret = SSL_connect (ssl);

if( ret == -1 ) {

std::cout<

ERR_print_errors_fp(stderr);

return -1;

}

ERR_print_errors_fp(stderr);

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

// 獲取cipher

std::cout<

// 獲取服務器端的證書

server_certificate = SSL_get_peer_certificate (ssl);

if( server_certificate != NULL ) {

std::cout<

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

if( str == NULL ) {

std::cout<

} else {

std::cout<

OPENSSL_free (str);

}

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

if( str == NULL ) {

std::cout<

} else {

std::cout<

OPENSSL_free (str);

}

X509_free (server_certificate);

} else {

std::cout<

return -1;

}

//? 數據交換? //

char? ? buf [4096];

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

if( ret == -1 ) {

std::cout<

return -1;

}

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

if( ret == -1 ) {

std::cout<

return -1;

}

buf[ret] = '\0';

std::cout<

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

/

// Cleanup //

/

close(client_socket);

SSL_free (ssl);

SSL_CTX_free (ctx);

return 0;

}

總結

以上是生活随笔為你收集整理的netty实现gmssl_gmssl国密总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。