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

內容介紹

  • 國密的雙證書體系,將證書按照使用目的的不同劃分為加密證書和簽名證書兩種,也就是兩對公私鑰,二者本質一致,均為SM2密鑰對,區別僅體現在用法
  • 國密CA體系中,加密密鑰對由CA產生,簽名密鑰對由用戶自己產生,那么加密密鑰涉及到的 私鑰是如何通過安全的方式由CA傳遞到用戶側呢?使用數字信封的機理
  • 從道理上來說兩個密鑰具有不同的屬性,邏輯上應該分開處理。其實最主要的原因是國家要保證必要的時候有能力對某些通訊進行監控,如果采用單證書,除了自己誰也無法解密(理論上如此),不利于國家安全。因此某些國家法律規定使用雙證書。如果擁有加密證書的私鑰,可以進行實時監控。使用過wireshark抓HTTPS包的朋友應該知道,如果配置了RSA密鑰,可以解密出HTTPS通信中的加密信息。

加密證書和私鑰的生成過程

  • 用戶產生簽名密鑰對,生成簽名證書的請求,發送簽名證書給CA
  • CA驗證用戶的簽名密鑰對,產生加密證書
  • CA生成對稱密鑰,使用用戶的簽名公鑰加密對稱密鑰,生成對稱秘鑰的密文
  • CA使用對稱密鑰對稱加密 加密證書所對應的私鑰,輸出加密私鑰的密文
  • CA將加密證書、對稱密鑰密文和加密私鑰的密文 返還給 用戶
  • 用戶使用簽名私鑰解密對稱密鑰的密文得到對稱密鑰
  • 用戶使用對稱密鑰解密加密私鑰,得到加密私鑰的明文

國標文檔

  • 《GMT 0024-2014 SSL VPN 技術規范》
  • 文檔的下載地址?GMSSL - 國密SSL實驗室
  • 對證書的介紹

注意事項

  • 雙證書與標準TLS報文格式一樣,但至少要包含兩個證書,簽名證書在前,加密證書在后。如果牽扯到證書鏈,問題就復雜了,而且協議這里也沒有規定清楚。是簽名證書 + 證書鏈 + 加密證書,還是簽名證書 + 加密證書 + 證書鏈?在實現中發現TASSL采用的是前者,而沃通測試網站采用后者。在編碼時請注意,最好是兩者都兼容。

參考鏈接

  • 國密SSL協議之雙證書體系_國密二三事的博客-CSDN博客_國密雙證書
  • 啥?雙證書?_云水木石的博客-CSDN博客
  • 新手入坑GMSSL(二)GMSSL雙證書生成_JagnDC的博客-CSDN博客_gmssl 雙證書
  • 新手入坑GMSSL(三)GMSSL雙證書與360國密瀏覽器通訊_JagnDC的博客-CSDN博客
  • 請問一個國密雙證書握手的問題 · Issue #274 · guanzhi/GmSSL · GitHub
  • https://github.com/guanzhi/GmSSL/issues/33
  • https://www.codeleading.com/article/21625213349/

最關鍵的參考鏈接

  • gmssl使用雙證書雙向認證的gmtl協議報錯crypto/sm2/sm2_sign.c 510: sm2_do_verifySSL3 alert write:fatal:decrypt error_MY CUP OF TEA的博客-CSDN博客?

命令行 模式

  • 新手入坑GMSSL(二)GMSSL雙證書生成_JagnDC的博客-CSDN博客_gmssl 雙證書
  • gmssl 國密ssl流程測試_viqjeee的博客-CSDN博客_gmssl s_server
  • GmSSL實現gmtls協議,也就是雙證書協議(簽名和加密雙證書)
  • 涉及到雙證書的文章中,一般都基于TASSL這個項目,它是由北京江南天安科技有限公司提出的支持國密證書和協議的項目
  • GitHub - jntass/TASSL: 已升級到TASSL-1.1.1k,下載鏈接https://github.com/jntass/TASSL-1.1.1k
  • 生成根證書、服務器和客戶端的簽名和加密證書,使用的腳本如下
  • TASSL/SM2certgen.sh at master · jntass/TASSL · GitHub
  • 證書的名字和類型
    • CA.key.pem和CA.cert.pem分別是CA私鑰和CA證書。
    • CE.cert.pem和CE.key.pem分別是客戶端的加密證書和對應的私鑰。
    • CS.cert.pem和CS.key.pem分別是客戶端的簽名證書和對應的私鑰。
    • SE.cert.pem和SE.key.pem分別是服務器的加密證書和對應的私鑰。
    • SS.cert.pem和SS.key.pem分別是服務器的簽名證書和對應的私鑰。
  • 官方的接口說明,openssl?s_server的參數中的-cert和-key分別用于指定證書和私鑰,但是還有個參數-dcert和-dkey,參考鏈接和官方解釋如下
  • /docs/man1.0.2/man1/openssl-s_server.html??????

-dcert filename,?-dkey keyname

specify an additional certificate and private key, these behave in the same manner as the?-cert?and?-key?options except there is no default if they are not specified (no additional certificate and key is used). As noted above some cipher suites require a certificate containing a key of a certain type. Some cipher suites need a certificate carrying an RSA key and some a DSS (DSA) key. By using RSA and DSS certificates and keys a server can support clients which only support RSA or DSS cipher suites by using an appropriate certificate.

-dcert文件名,-dkey密鑰名
指定一個額外的證書和私鑰,它們的行為方式與-cert和-key選項相同,除非沒有指定它們,否則沒有默認值(不使用額外的證書和密鑰)。如上所述,一些密碼套件需要包含特定類型密鑰的證書。一些密碼套件需要攜帶RSA密鑰和一些DSS (DSA)密鑰的證書。通過使用RSA和DSS證書和密鑰,服務器可以通過使用適當的證書來支持僅支持RSA或DSS密碼套件的客戶端。

雙證書雙向認證?

服務端

  • 在設置雙證書時,需要先設置簽名證書,然后再設置加密證書,具體可參考源碼。
  • 服務端執行命令 需要在指定的文件下執行
  • 必須要有 verify,verify是開啟gmtls雙向證書認證的關鍵,也就是對等證書驗證,客戶端也會驗證服務端的證書
  • gmssl s_server -gmtls -accept 44330 -key SS.key.pem -cert SS.cert.pem -dkey SE.key.pem -dcert SE.cert.pem -CAfile CA.cert.pem -state -verify 1
chy-cpabe@ubuntu:~/GMSSL_certificate/sm2Certs$ gmssl s_server -gmtls -accept 44330 -key SS.key.pem -cert SS.cert.pem -dkey SE.key.pem -dcert SE.cert.pem -CAfile CA.cert.pem -state -verify 1
verify depth is 1
Using default temp DH parameters
[GMTLS_DEBUG] set sm2 signing certificate
[GMTLS_DEBUG] set sm2 signing private key
[GMTLS_DEBUG] set sm2 encryption certificate
[GMTLS_DEBUG] set sm2 decryption private key
ACCEPT
SSL_accept:before SSL initialization
SSL_accept:before SSL initialization
SSL_accept:SSLv3/TLS read client hello
SSL_accept:SSLv3/TLS write server hello
SSL_accept:SSLv3/TLS write certificate
SSL_accept:SSLv3/TLS write key exchange
SSL_accept:SSLv3/TLS write certificate request
SSL_accept:SSLv3/TLS write server done
SSL_accept:SSLv3/TLS write server done
depth=1 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = SORB of TASS, CN = Test CA (SM2)
verify return:1
depth=0 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = BSRC of TASS, CN = client sign (SM2)
verify return:1
SSL_accept:SSLv3/TLS read client certificate
ssl_get_algorithm2=f227000008x
SSL_accept:SSLv3/TLS read client key exchange
SSL_accept:SSLv3/TLS read certificate verify
SSL_accept:SSLv3/TLS read change cipher spec
SSL_accept:SSLv3/TLS read finished
SSL_accept:SSLv3/TLS write change cipher spec
SSL_accept:SSLv3/TLS write finished
-----BEGIN SSL SESSION PARAMETERS-----
MIICmAIBAQICAQEEAuATBCAWcAdtfPyMiEJmINUd/e/AmYdNqNTalV1AAbACRSQE
CgQwtuURXPYQpQ7gQIZ3fWRd9QpsP0Zi57oDT1D/X1xVBL3wy9yrr/BOpRw2afsu
4DH3oQYCBGMw/gSiBAICHCCjggIfMIICGzCCAcGgAwIBAgIJAIVjx+dwZIdmMAoG
CCqBHM9VAYN1MIGCMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
FTATBgNVBAsMDFNPUkIgb2YgVEFTUzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAe
Fw0yMDA2MjAxMDE4MjZaFw0yNDA3MjkxMDE4MjZaMIGGMQswCQYDVQQGEwJDTjEL
MAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcg
Sk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgG
A1UEAwwRY2xpZW50IHNpZ24gKFNNMikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNC
AARV/eII1n2NVqYjwt9r9A5Eh6Z0iG+WUpsw4sGxhfKL0vr0OKcur6DZqjqLDSCr
ZEhU6yuntNtaW+pexPblqXAroxowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAK
BggqgRzPVQGDdQNIADBFAiEAiX+PoCNW/n9SDbv6/o+NyCCV/7kBgunc7w5b7xGm
4RICIBMDlLjPZE2ACYhu1Wjqph23PfMPMgae4+Gtd7wzFz2UpAYEBAEAAAA=
-----END SSL SESSION PARAMETERS-----
Client certificate
-----BEGIN CERTIFICATE-----
MIICGzCCAcGgAwIBAgIJAIVjx+dwZIdmMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjZaFw0yNDA3
MjkxMDE4MjZaMIGGMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgGA1UEAwwRY2xpZW50IHNpZ24gKFNN
MikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAARV/eII1n2NVqYjwt9r9A5Eh6Z0
iG+WUpsw4sGxhfKL0vr0OKcur6DZqjqLDSCrZEhU6yuntNtaW+pexPblqXAroxow
GDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNIADBFAiEAiX+P
oCNW/n9SDbv6/o+NyCCV/7kBgunc7w5b7xGm4RICIBMDlLjPZE2ACYhu1Wjqph23
PfMPMgae4+Gtd7wzFz2U
-----END CERTIFICATE-----
subject=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=client sign (SM2)
issuer=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
Shared ciphers:SM9-WITH-SMS4-SM3:SM9DHE-WITH-SMS4-SM3:SM2-WITH-SMS4-SM3:SM2DHE-WITH-SMS4-SM3:RSA-WITH-SMS4-SHA1:RSA-WITH-SMS4-SM3
CIPHER is SM2-WITH-SMS4-SM3
Secure Renegotiation IS supported

客戶端?

  • 客戶端執行代碼和執行結果??
  • gmssl s_client -gmtls -connect localhost:44330 -key CS.key.pem -cert CS.cert.pem -dkey CE.key.pem -dcert CE.cert.pem -CAfile CA.cert.pem -state -showcerts
chy-cpabe@ubuntu:~/GMSSL_certificate/sm2Certs$ gmssl s_client -gmtls -connect localhost:44330 -key CS.key.pem -cert CS.cert.pem -dkey CE.key.pem -dcert CE.cert.pem -CAfile CA.cert.pem -state -showcerts
[GMTLS_DEBUG] set sm2 signing certificate
[GMTLS_DEBUG] set sm2 signing private key
[GMTLS_DEBUG] set sm2 encryption certificate
[GMTLS_DEBUG] set sm2 decryption private key
CONNECTED(00000003)
SSL_connect:before SSL initialization
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
depth=1 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = SORB of TASS, CN = Test CA (SM2)
verify return:1
depth=0 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = BSRC of TASS, CN = server sign (SM2)
verify return:1
SSL_connect:SSLv3/TLS read server certificate
Z=BCDCCB61AADD790C076DAC60ED09DDD5285A906A4025DD748DA2FB5816464C58
C=00021E3082021A308201C0A0030201020209008563C7E770648765300A06082A811CCF55018375308182310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C534F5242206F6620544153533116301406035504030C0D546573742043412028534D3229301E170D3230303632303130313832365A170D3234303732393130313832365A308185310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C42535243206F6620544153533119301706035504030C1073657276657220656E632028534D32293059301306072A8648CE3D020106082A811CCF5501822D03420004B999853302F02CC522CC4CCA287019E86B901FC24E3CCF9A61B93BB177B28C2CE8E23C5C522DF73C23F7AC36FF688CB2E685A3FA4770103F7C99EFC32D06C11FA31A301830090603551D1304023000300B0603551D0F040403020338300A06082A811CCF550183750348003045022100EC4368F400870BED441817AF4D359BDC61A9EDFDDEE54AB0C185084B450C46B902206E0C3A08BC584590046DC85603CD4E8A51F97D9669B1ACA3E2A3627BE61D49A2
SSL_connect:SSLv3/TLS read server key exchange
SSL_connect:SSLv3/TLS read server certificate request
SSL_connect:SSLv3/TLS read server done
SSL_connect:SSLv3/TLS write client certificate
SSL_connect:SSLv3/TLS write client key exchange
ssl_get_algorithm2=3268600008x
SSL_connect:SSLv3/TLS write certificate verify
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS read change cipher spec
SSL_connect:SSLv3/TLS read finished
---
Certificate chain0 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
-----BEGIN CERTIFICATE-----
MIICGjCCAcGgAwIBAgIJAIVjx+dwZIdkMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjVaFw0yNDA3
MjkxMDE4MjVaMIGGMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgGA1UEAwwRc2VydmVyIHNpZ24gKFNN
MikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAS0lHzt7CkOzCtyf6VwCqoT2PYD
CL/AJrCsHa+6lE8wDZ7DShI2bvfmrpavndEW67CHQOlO0q6/aoEB0PoAgpopoxow
GDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNHADBEAiB06JWp
uxFbGBfvG9juhe2Umu/auI1H2XeMdvDjbOtfuQIgMXT8jewkzq9TR3OPzRTkZCRH
3H+xKEb8r8JsEEStwaU=
-----END CERTIFICATE-----1 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server enc (SM2)i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
-----BEGIN CERTIFICATE-----
MIICGjCCAcCgAwIBAgIJAIVjx+dwZIdlMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjZaFw0yNDA3
MjkxMDE4MjZaMIGFMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEZMBcGA1UEAwwQc2VydmVyIGVuYyAoU00y
KTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABLmZhTMC8CzFIsxMyihwGehrkB/C
TjzPmmG5O7F3sows6OI8XFIt9zwj96w2/2iMsuaFo/pHcBA/fJnvwy0GwR+jGjAY
MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgM4MAoGCCqBHM9VAYN1A0gAMEUCIQDsQ2j0
AIcL7UQYF69NNZvcYant/d7lSrDBhQhLRQxGuQIgbgw6CLxYRZAEbchWA81OilH5
fZZpsayj4qNie+YdSaI=
-----END CERTIFICATE-----2 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
-----BEGIN CERTIFICATE-----
MIICWjCCAgCgAwIBAgIJAP5W2mLaOWq5MAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjVaFw0yNDA3
MjkxMDE4MjVaMIGCMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
FTATBgNVBAsMDFNPUkIgb2YgVEFTUzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTBZ
MBMGByqGSM49AgEGCCqBHM9VAYItA0IABArjN7ag+H8D12eqXJpMeTOR9m3sB2RC
ojH7fZPB77SDfHZb9g1lcqUhrug0nw2F8wBMsLfjvsK3wQn/ryi3YvSjXTBbMB0G
A1UdDgQWBBRCcBGiEpd09qSpUlkiGkZ+q+CFbDAfBgNVHSMEGDAWgBRCcBGiEpd0
9qSpUlkiGkZ+q+CFbDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzP
VQGDdQNIADBFAiBjdylWVsUoTRcHu9DoMHv4lgtYJMf2xHAGLoJUjmbizAIhAOFD
i3EmFVUgGVdgbnztFZcBLxtBzIAh/Q4Q3dm3/MFu
-----END CERTIFICATE-----
---
Server certificate
subject=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)
issuer=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
---
Acceptable client certificate CA names
/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
Client Certificate Types: RSA sign, DSA sign
---
SSL handshake has read 2121 bytes and written 2115 bytes
Verification: OK
---
New, GMTLSv1.1, Cipher is SM2-WITH-SMS4-SM3
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:Protocol  : GMTLSv1.1Cipher    : SM2-WITH-SMS4-SM3Session-ID: 1670076D7CFC8C88426620D51DFDEFC099874DA8D4DA955D4001B0024524040ASession-ID-ctx: Master-Key: B6E5115CF610A50EE04086777D645DF50A6C3F4662E7BA034F50FF5F5C5504BDF0CBDCABAFF04EA51C3669FB2EE031F7PSK identity: NonePSK identity hint: NoneSRP username: NoneStart Time: 1664155140Timeout   : 7200 (sec)Verify return code: 0 (ok)Extended master secret: no
---

雙證書單向認證?

  • 同時指定簽名和加密證書 且 采用雙證書單向認證
  • 服務端執行代碼
  • gmssl s_server -gmtls -accept 44330 -key SS.key.pem -cert SS.cert.pem -dkey SE.key.pem -dcert SE.cert.pem -CAfile CA.cert.pem -state
  • 只需要將verify刪除,就由雙向認證變成了單項認證
  • -state參數表示打印跟多信息,方便調試

s_server: Cannot open input file gmcrt/2_sign.crt, No such file or directory
s_server: Use -help for summary.
chy-cpabe@ubuntu:~/test_double_ssl/GMSSL雙證書demo/sm2Certs$ ls
CA.cert.pem  CA.key.pem  CA.pem  CE.cert.pem  CE.key.pem  CE.pem  CS.cert.pem  CS.key.pem  CS.pem  SE.cert.pem  SE.key.pem  SE.pem  SS.cert.pem  SS.key.pem  SS.pem
chy-cpabe@ubuntu:~/test_double_ssl/GMSSL雙證書demo/sm2Certs$ gmssl s_server -gmtls -accept 44330 -key SS.key.pem -cert SS.cert.pem  -dkey SE.key.pem -dcert SE.cert.pem -CAfile CA.cert.pem -state
Using default temp DH parameters
[GMTLS_DEBUG] set sm2 signing certificate
[GMTLS_DEBUG] set sm2 signing private key
[GMTLS_DEBUG] set sm2 encryption certificate
[GMTLS_DEBUG] set sm2 decryption private key
ACCEPT
SSL_accept:before SSL initialization
SSL_accept:before SSL initialization
ssl_get_algorithm2=2b81000008x
SSL_accept:SSLv3/TLS read client hello
SSL_accept:SSLv3/TLS write server hello
SSL_accept:SSLv3/TLS write certificate
SSL_accept:SSLv3/TLS write key exchange
SSL_accept:SSLv3/TLS write server done
SSL_accept:SSLv3/TLS write server done
SSL_accept:SSLv3/TLS read client key exchange
SSL_accept:SSLv3/TLS read change cipher spec
SSL_accept:SSLv3/TLS read finished
SSL_accept:SSLv3/TLS write change cipher spec
SSL_accept:SSLv3/TLS write finished
-----BEGIN SSL SESSION PARAMETERS-----
MHUCAQECAgEBBALgEwQg4tsFtm05e9thEdmOsDjCdEY797x1PAcVaGWd8chdLuoE
MDqjvlXZek3vSlC1q+aYT7NA40D6C7sbR0gNowPIhMfVan396kWxthLUmXIgz3t1
5qEGAgRjAfsxogQCAhwgpAYEBAEAAAA=
-----END SSL SESSION PARAMETERS-----
Shared ciphers:SM9-WITH-SMS4-SM3:SM9DHE-WITH-SMS4-SM3:SM2-WITH-SMS4-SM3:SM2DHE-WITH-SMS4-SM3:RSA-WITH-SMS4-SHA1:RSA-WITH-SMS4-SM3
CIPHER is SM2-WITH-SMS4-SM3
Secure Renegotiation IS supported
  • 客戶端執行代碼
  • gmssl s_client -gmtls -connect localhost:44330 -key CS.key.pem -cert CS.cert.pem -dkey CE.key.pem -dcert CE.cert.pem -CAfile CA.cert.pem -state
  • 可以看出,現在使用的協議已經變成gmtlsv1.1
  • SSL-Session:
  • ? ? Protocol ?: GMTLSv1.1

[GMTLS_DEBUG] set sm2 signing certificate
[GMTLS_DEBUG] set sm2 signing private key
[GMTLS_DEBUG] set sm2 encryption certificate
[GMTLS_DEBUG] set sm2 decryption private key
CONNECTED(00000003)
SSL_connect:before SSL initialization
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
depth=1 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = SORB of TASS, CN = Test CA (SM2)
verify return:1
depth=0 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = BSRC of TASS, CN = server sign (SM2)
verify return:1
SSL_connect:SSLv3/TLS read server certificate
Z=BCDCCB61AADD790C076DAC60ED09DDD5285A906A4025DD748DA2FB5816464C58
C=00021E3082021A308201C0A0030201020209008563C7E770648765300A06082A811CCF55018375308182310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C534F5242206F6620544153533116301406035504030C0D546573742043412028534D3229301E170D3230303632303130313832365A170D3234303732393130313832365A308185310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C42535243206F6620544153533119301706035504030C1073657276657220656E632028534D32293059301306072A8648CE3D020106082A811CCF5501822D03420004B999853302F02CC522CC4CCA287019E86B901FC24E3CCF9A61B93BB177B28C2CE8E23C5C522DF73C23F7AC36FF688CB2E685A3FA4770103F7C99EFC32D06C11FA31A301830090603551D1304023000300B0603551D0F040403020338300A06082A811CCF550183750348003045022100EC4368F400870BED441817AF4D359BDC61A9EDFDDEE54AB0C185084B450C46B902206E0C3A08BC584590046DC85603CD4E8A51F97D9669B1ACA3E2A3627BE61D49A2
SSL_connect:SSLv3/TLS read server key exchange
SSL_connect:SSLv3/TLS read server done
SSL_connect:SSLv3/TLS write client key exchange
SSL_connect:SSLv3/TLS write change cipher spec
ssl_get_algorithm2=2790100008x
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS write finished
SSL_connect:SSLv3/TLS read change cipher spec
SSL_connect:SSLv3/TLS read finished
---
Certificate chain0 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)1 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server enc (SM2)i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)2 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICGjCCAcGgAwIBAgIJAIVjx+dwZIdkMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjVaFw0yNDA3
MjkxMDE4MjVaMIGGMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgGA1UEAwwRc2VydmVyIHNpZ24gKFNN
MikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAS0lHzt7CkOzCtyf6VwCqoT2PYD
CL/AJrCsHa+6lE8wDZ7DShI2bvfmrpavndEW67CHQOlO0q6/aoEB0PoAgpopoxow
GDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNHADBEAiB06JWp
uxFbGBfvG9juhe2Umu/auI1H2XeMdvDjbOtfuQIgMXT8jewkzq9TR3OPzRTkZCRH
3H+xKEb8r8JsEEStwaU=
-----END CERTIFICATE-----
subject=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)
issuer=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
---
No client certificate CA names sent
---
SSL handshake has read 1973 bytes and written 320 bytes
Verification: OK
---
New, GMTLSv1.1, Cipher is SM2-WITH-SMS4-SM3
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:Protocol  : GMTLSv1.1Cipher    : SM2-WITH-SMS4-SM3Session-ID: E24D8195A9D25F9A6B877C63A85979492FA5199E58FA512A95915E33BA7A418BSession-ID-ctx: Master-Key: 2ED26139965074A55F65D011A370DF7A4672A0FC7BBB4A0ED991DCD55A6231E92B5A09225BFE9F1ABD0546F1F75885A2PSK identity: NonePSK identity hint: NoneSRP username: NoneStart Time: 1661073328Timeout   : 7200 (sec)Verify return code: 0 (ok)Extended master secret: no
---
  • 客戶端命令
  • gmssl s_client -gmtls -connect localhost:44330 -key CS.key.pem -cert CS.cert.pem -dkey CE.key.pem -dcert CE.cert.pem -CAfile CA.cert.pem -state
gmssl s_client -gmtls -connect localhost:44330 -key CS.key.pem -cert CS.cert.pem -dkey CE.key.pem -dcert CE.cert.pem -CAfile CA.cert.pem -state
[GMTLS_DEBUG] set sm2 signing certificate
[GMTLS_DEBUG] set sm2 signing private key
[GMTLS_DEBUG] set sm2 encryption certificate
[GMTLS_DEBUG] set sm2 decryption private key
CONNECTED(00000003)
SSL_connect:before SSL initialization
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS write client hello
SSL_connect:SSLv3/TLS read server hello
depth=1 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = SORB of TASS, CN = Test CA (SM2)
verify return:1
depth=0 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = BSRC of TASS, CN = server sign (SM2)
verify return:1
SSL_connect:SSLv3/TLS read server certificate
Z=BCDCCB61AADD790C076DAC60ED09DDD5285A906A4025DD748DA2FB5816464C58
C=00021E3082021A308201C0A0030201020209008563C7E770648765300A06082A811CCF55018375308182310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C534F5242206F6620544153533116301406035504030C0D546573742043412028534D3229301E170D3230303632303130313832365A170D3234303732393130313832365A308185310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C42535243206F6620544153533119301706035504030C1073657276657220656E632028534D32293059301306072A8648CE3D020106082A811CCF5501822D03420004B999853302F02CC522CC4CCA287019E86B901FC24E3CCF9A61B93BB177B28C2CE8E23C5C522DF73C23F7AC36FF688CB2E685A3FA4770103F7C99EFC32D06C11FA31A301830090603551D1304023000300B0603551D0F040403020338300A06082A811CCF550183750348003045022100EC4368F400870BED441817AF4D359BDC61A9EDFDDEE54AB0C185084B450C46B902206E0C3A08BC584590046DC85603CD4E8A51F97D9669B1ACA3E2A3627BE61D49A2
SSL_connect:SSLv3/TLS read server key exchange
SSL_connect:SSLv3/TLS read server certificate request
SSL_connect:SSLv3/TLS read server done
SSL_connect:SSLv3/TLS write client certificate
SSL_connect:SSLv3/TLS write client key exchange
ssl_get_algorithm2=3c3f900008x
SSL_connect:SSLv3/TLS write certificate verify
SSL_connect:SSLv3/TLS write change cipher spec
SSL_connect:SSLv3/TLS write finished
SSL3 alert read:fatal:decrypt error
SSL_connect:error in SSLv3/TLS write finished
140016949239808:error:1409441B:SSL routines:ssl3_read_bytes:tlsv1 alert decrypt error:ssl/record/rec_layer_s3.c:1385:SSL alert number 51
---
Certificate chain0 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)1 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server enc (SM2)i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)2 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICGjCCAcGgAwIBAgIJAIVjx+dwZIdkMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjVaFw0yNDA3
MjkxMDE4MjVaMIGGMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgGA1UEAwwRc2VydmVyIHNpZ24gKFNN
MikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAS0lHzt7CkOzCtyf6VwCqoT2PYD
CL/AJrCsHa+6lE8wDZ7DShI2bvfmrpavndEW67CHQOlO0q6/aoEB0PoAgpopoxow
GDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNHADBEAiB06JWp
uxFbGBfvG9juhe2Umu/auI1H2XeMdvDjbOtfuQIgMXT8jewkzq9TR3OPzRTkZCRH
3H+xKEb8r8JsEEStwaU=
-----END CERTIFICATE-----
subject=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)
issuer=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
---
Acceptable client certificate CA names
/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
Client Certificate Types: RSA sign, DSA sign
---
SSL handshake has read 2037 bytes and written 2116 bytes
Verification: OK
---
New, GMTLSv1.1, Cipher is SM2-WITH-SMS4-SM3
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:Protocol  : GMTLSv1.1Cipher    : SM2-WITH-SMS4-SM3Session-ID: 12664AE82CE989580C27B14AFF7487B19FF1C159C94291A0B76AA5F80D28317FSession-ID-ctx: Master-Key: AD4D5164B7F54B9FA1F74A7A569C6B6E75CFD96967AB7519658C33E9C6FB8851EBCF1B10E175E736E9C7127E5FA8D32DPSK identity: NonePSK identity hint: NoneSRP username: NoneStart Time: 1661074697Timeout   : 7200 (sec)Verify return code: 0 (ok)Extended master secret: no
---

雙證書雙向認證-代碼實現

?參考鏈接

  • GmSSL編程實現gmtls協議C/S通信(BIO版本)_葉之香的博客-CSDN博客
  • GmSSL編程實現gmtls協議C/S通信(非BIO版本)_葉之香的博客-CSDN博客

?注意事項

  • 基于TASSL開源項目中的Tassl_demo/mk_tls_cert 下的 SM2certgen.sh 腳本,共生成 15 個 PEM 文件,即根證書、服務端和客戶端的簽名和加密證書
  • 上述參考鏈接里面的下面這句話是錯誤的,服務端都不驗證客戶端身份了,還叫雙向認證嘛??
  • 修改后代碼如下
    // 是否要求校驗對方證書 此處不驗證客戶端身份所以為: SSL_VERIFY_NONESSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
  • 如果報sm2_do_verify的錯誤信息,參考下面鏈接,修改源碼重新編譯
  • gmssl使用雙證書雙向認證的gmtl協議報錯crypto/sm2/sm2_sign.c 510: sm2_do_verifySSL3 alert write:fatal:decrypt error_MY CUP OF TEA的博客-CSDN博客?

?服務端代碼

#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 1500//#define CA_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CA.cert.pem"
//#define SIGN_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/SS.cert.pem"
//#define SIGN_KEY_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/SS.key.pem"
//#define ENCODE_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/SE.cert.pem"
//#define ENCODE_KEY_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/SE.key.pem"#define CA_CERT_FILE "/home/chy-cpabe/tmp/second/rootcert.pem"
#define SIGN_CERT_FILE "/home/chy-cpabe/tmp/second/sign.pem"
#define SIGN_KEY_FILE "/home/chy-cpabe/tmp/second/sign.key"
#define ENCODE_CERT_FILE "/home/chy-cpabe/tmp/second/encrypt.pem"
#define ENCODE_KEY_FILE "/home/chy-cpabe/tmp/second/encrypt.key"void 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( GMTLS_server_method())))		//using sm3, TLSv1_2_method{ERR_print_errors_fp(stderr);break;}
//        SSL_CTX_set_security_level(ctx,0);// 雙向驗證// 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, CA_CERT_FILE, nullptr) != 1){printf("SSL_CTX_load_verify_locations error\n");ERR_print_errors_fp(stderr);break;}// 簽名證書和對應私鑰if( 0>=SSL_CTX_use_certificate_file(ctx, SIGN_CERT_FILE, SSL_FILETYPE_PEM/*SSL_FILETYPE_ASN1*/) ) /* 為SSL會話加載用戶證書 */{printf("SSL_CTX_use_certificate_file error!\n");ERR_print_errors_fp(stderr);break;}if( 0>=SSL_CTX_use_PrivateKey_file(ctx, SIGN_KEY_FILE, SSL_FILETYPE_PEM/*SSL_FILETYPE_ASN1*/) ) /* 為SSL會話加載用戶私鑰 */{printf("SSL_CTX_use_PrivateKey_file error!\n");ERR_print_errors_fp(stderr);break;}// 加密證書和對應私鑰if(SSL_CTX_use_certificate_file(ctx, ENCODE_CERT_FILE, SSL_FILETYPE_PEM) <= 0){printf("SSL_CTX_use_certificate_file error!\n");ERR_print_errors_fp(stderr);return -1;}if(SSL_CTX_use_PrivateKey_file(ctx, ENCODE_KEY_FILE, SSL_FILETYPE_PEM) <= 0){printf("SSL_CTX_use_PrivateKey_file error!\n");ERR_print_errors_fp(stderr);return -1;}/* 檢查用戶私鑰是否正確 */if(!SSL_CTX_check_private_key(ctx))                                 										 /* 驗證私鑰和證書是否相符 */{printf("SSL_CTX_check_private_key error!\n");ERR_print_errors_fp(stderr);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;
}

客戶端代碼

#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 1024
//#define CA_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CA.cert.pem"
//#define CS_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CS.cert.pem"
//#define CS_KEY_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CS.key.pem"
//#define CE_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CE.cert.pem"
//#define CE_KEY_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CE.key.pem"#define CA_CERT_FILE "/home/chy-cpabe/tmp/first/rootcert.pem"
#define CS_CERT_FILE "/home/chy-cpabe/tmp/first/sign.pem"
#define CS_KEY_FILE "/home/chy-cpabe/tmp/first/sign.key"
#define CE_CERT_FILE "/home/chy-cpabe/tmp/first/encrypt.pem"
#define CE_KEY_FILE "/home/chy-cpabe/tmp/first/encrypt.key"
void 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(GMTLS_client_method())) )    //使用SSL_CTX_new()創建會話環境,建立連接時要使用協議由TLS_client_method()來定,服務器由對應的TLS_server_method()來定。如果這一步出錯,需要查看錯誤棧來查看原因{printf("SSL_CTX_new error!\n");ERR_print_errors_fp(stderr);break;}// 雙向驗證// 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_set_cipher_list(ctx, "ECC-SM2-WITH-SM4-SM3") <= 0){
//            printf("SSL_CTX_set_cipher_list error!\n");
//            ERR_print_errors_fp(stderr);
//            exit(1);
//        }// 設置信任根證書if(SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, nullptr) != 1){printf("SSL_CTX_load_verify_locations error!\n");ERR_print_errors_fp(stderr);exit(1);}// 簽名證書和對應私鑰if (SSL_CTX_use_certificate_file(ctx, CS_CERT_FILE, SSL_FILETYPE_PEM) <= 0){printf("SSL_CTX_use_certificate_file error!\n");ERR_print_errors_fp(stderr);exit(1);}if (SSL_CTX_use_PrivateKey_file(ctx, CS_KEY_FILE, SSL_FILETYPE_PEM) <= 0){printf("SSL_CTX_use_PrivateKey_file error!\n");ERR_print_errors_fp(stderr);exit(1);}// 加密證書和對應私鑰if(SSL_CTX_use_certificate_file(ctx, CE_CERT_FILE, SSL_FILETYPE_PEM) <= 0){printf("SSL_CTX_use_certificate_file error!\n");ERR_print_errors_fp(stderr);return -1;}if(SSL_CTX_use_PrivateKey_file(ctx, CE_KEY_FILE, SSL_FILETYPE_PEM) <= 0){printf("SSL_CTX_use_PrivateKey_file error!\n");ERR_print_errors_fp(stderr);return -1;}//判定私鑰是否正確if (!SSL_CTX_check_private_key(ctx)) {printf("SSL_CTX_check_private_key error!\n");ERR_print_errors_fp(stderr);exit(1);}
//        SSL_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]);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("SSL_export_keying_material error,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;
}

注意事項

  • GitHub - jntass/TASSL: 已升級到TASSL-1.1.1k,下載鏈接https://github.com/jntass/TASSL-1.1.1k
  • GitHub - jntass/TASSL-1.1.1k? ?目前最新的版本
  • TASSL為了支持國密雙證書體系添加了很多函數

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

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

相關文章

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;無論經受什么…

《Java8實戰》筆記(15):面向對象和函數式編程的混合-Java 8和Scala的比較

面向對象和函數式編程的混合&#xff1a;Java 8和Scala的比較 Scala是一種混合了面向對象和函數式編程的語言。它常常被看作Java的一種替代語言&#xff0c;程序員們希望在運行于JVM上的靜態類型語言中使用函數式特性&#xff0c;同時又期望保持Java體驗的一致性。和Java比較起…

函數指針作為形參進行調用

代碼 兩個代碼均位于namespace作用域之內addOne將傳遞進來的形參進行加一&#xff0c;然后返回performance_test函數主要是想簡化函數調用&#xff0c;兩個形參&#xff0c;第一個表示循環的次數&#xff0c;第二個是帶參數的函數指針&#xff0c;函數內部初始化start和end兩個…

python中fetchall_Python連接MySQL并使用fetchall()方法過濾特殊字符

來一個簡單的例子&#xff0c;看Python如何操作數據庫&#xff0c;相比Java的JDBC來說&#xff0c;確實非常簡單&#xff0c;省去了很多復雜的重復工作&#xff0c;只關心數據的獲取與操作。準備工作需要有相應的環境和模塊&#xff1a;Ubuntu 14.04 64bitPython 2.7.6MySQLdb注…

《Java8實戰》筆記(16):結論以及Java的未來

結論以及Java的未來 回顧Java8的語言特性 行為參數化&#xff08;Lambda以及方法引用&#xff09; 流 CompletableFuture Optional 默認方法 Java的未來 集合 類型系統的改進 聲明位置變量 更多的類型推斷 模式匹配 更加豐富的泛型形式 具化泛型 泛型中特別為函…

解決吉大正源(身份認證網關|USBKey)和gmssl(server|client)使用gmtl協議交叉互通報錯tlsv1 alert decrypt error

報錯內容 SSL_connect:error in SSLv3/TLS write finished140057291788288:error:1409441B:SSL routines:ssl3_read_bytes:tlsv1 alert decrypt error:ssl/record/rec_layer_s3.c:1385:SSL alert number 51 報錯原因 gmssl庫生成 certificate verify 消息時&#xff0c;對自客…

12無法使用otg_12個冷知識:或許只能看看而無法使用,但卻真實存在著

12個或許只能看看而無法使用&#xff0c;但卻真實存在著。臉紅一所有已知動物中&#xff0c;唯一可以臉紅的是人類。二有些地區將雨水歸類為公共財物&#xff0c;作為公共財物是不允許收集的&#xff0c;違反者將面臨處罰。三世界上汽車研發成本最高的一款車是福特蒙迪歐&#…

《Java8實戰》筆記匯總

《Java8實戰》筆記&#xff08;01&#xff09;&#xff1a;為什么要關心Java8 《Java8實戰》筆記&#xff08;02&#xff09;&#xff1a;通過行為參數傳遞代碼 《Java8實戰》筆記&#xff08;03&#xff09;&#xff1a;Lambda表達式 《Java8實戰》筆記&#xff08;04&…

三目運算符_C語言知識點:運算符的優先級和結合性

運算符是一種告訴編譯器執行特定的數學或邏輯操作的符號。C語言內置了豐富的運算符&#xff0c;大體可分為10類&#xff1a;算術運算符、關系運算符、邏輯運算符、位操作運算符、賦值運算符、條件運算符、逗號運算符、指針運算符、求字節數運算符和特殊運算符。根據運算符可操作…

可以直接進行運算么_WORD辦公技巧:如何直接在WORD中進行加法、乘法運算?

排版目標下圖文檔中有一張2020年&#xff11;&#xff0d;&#xff13;月口罩購買情況統計表&#xff0c;數據量并不大&#xff0c;我們想不動用excel表格進行統計&#xff0c;直接利用WORD自帶的函數公式計算出表格內空白單元格的數值。其中&#xff0c;金額&#xff1d;單價&…

對dladdr未定義的引用

參考鏈接 c - 為什么我得到“對dladdr的未定義引用”&#xff0c;即使是這個簡單程序的-ldl&#xff1f; | 碼農俱樂部 - Golang中國 - Go語言中文社區 注意事項 dladdr需要與-ldl鏈接&#xff0c;且-ldl放置在鏈接的最后 CMakeLists.txt 模板 cmake_minimum_required(VERSI…

如何優雅互換Map鍵與值

一般方法 //map must be a bijection in order for this to work properly public static <K,V> HashMap<V,K> reverse(Map<K,V> map) {HashMap<V,K> rev new HashMap<V, K>();for(Map.Entry<K,V> entry : map.entrySet())rev.put(entry…

python程序設計題怎么寫_《Python語言程序設計基礎》第1章程序練習題

本文為中國大學MOOC《Python語言程序設計》課程學習筆記&#xff0c;課程主講&#xff1a;嵩天老師&#xff0c;練習平臺&#xff1a;Python123&#xff0c;參考教材&#xff1a;《Python語言程序設計基礎》1.1 字符串拼接Str1 input("請輸入一個人的名字&#xff1a;&qu…

《劍指Offer》36:二叉搜索樹與雙向鏈表

題目 輸入一棵二叉搜索樹&#xff0c;將該二叉搜索樹轉換成一個排序的雙向鏈表。要求不能創建任何新的節點&#xff0c;只能調整樹中節點指針的指向。比如&#xff0c;輸入下圖中的二叉搜索樹&#xff0c;輸出轉換之后的排序雙向鏈表。 二叉樹節點的定義如下&#xff1a; pub…