当前位置:   article > 正文

国密gmtls协议-双证书体系的服务端和客户端通信代码_gmtlsv1

gmtlsv1

内容介绍

  • 国密的双证书体系,将证书按照使用目的的不同划分为加密证书和签名证书两种,也就是两对公私钥,二者本质一致,均为SM2密钥对,区别仅体现在用法
  • 国密CA体系中,加密密钥对由CA产生,签名密钥对由用户自己产生,那么加密密钥涉及到的 私钥是如何通过安全的方式由CA传递到用户侧呢?使用数字信封的机理
  • 从道理上来说两个密钥具有不同的属性,逻辑上应该分开处理。其实最主要的原因是国家要保证必要的时候有能力对某些通讯进行监控,如果采用单证书,除了自己谁也无法解密(理论上如此),不利于国家安全。因此某些国家法律规定使用双证书。如果拥有加密证书的私钥,可以进行实时监控。使用过wireshark抓HTTPS包的朋友应该知道,如果配置了RSA密钥,可以解密出HTTPS通信中的加密信息。

加密证书和私钥的生成过程

  • 用户产生签名密钥对,生成签名证书的请求,发送签名证书给CA
  • CA验证用户的签名密钥对,产生加密证书
  • CA生成对称密钥,使用用户的签名公钥加密对称密钥,生成对称秘钥的密文
  • CA使用对称密钥对称加密 加密证书所对应的私钥,输出加密私钥的密文
  • CA将加密证书、对称密钥密文和加密私钥的密文 返还给 用户
  • 用户使用签名私钥解密对称密钥的密文得到对称密钥
  • 用户使用对称密钥解密加密私钥,得到加密私钥的明文

国标文档

注意事项

  • 双证书与标准TLS报文格式一样,但至少要包含两个证书,签名证书在前,加密证书在后。如果牵扯到证书链,问题就复杂了,而且协议这里也没有规定清楚。是签名证书 + 证书链 + 加密证书,还是签名证书 + 加密证书 + 证书链?在实现中发现TASSL采用的是前者,而沃通测试网站采用后者。在编码时请注意,最好是两者都兼容。

参考链接

最关键的参考链接

命令行 模式

-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
  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
  2. verify depth is 1
  3. Using default temp DH parameters
  4. [GMTLS_DEBUG] set sm2 signing certificate
  5. [GMTLS_DEBUG] set sm2 signing private key
  6. [GMTLS_DEBUG] set sm2 encryption certificate
  7. [GMTLS_DEBUG] set sm2 decryption private key
  8. ACCEPT
  9. SSL_accept:before SSL initialization
  10. SSL_accept:before SSL initialization
  11. SSL_accept:SSLv3/TLS read client hello
  12. SSL_accept:SSLv3/TLS write server hello
  13. SSL_accept:SSLv3/TLS write certificate
  14. SSL_accept:SSLv3/TLS write key exchange
  15. SSL_accept:SSLv3/TLS write certificate request
  16. SSL_accept:SSLv3/TLS write server done
  17. SSL_accept:SSLv3/TLS write server done
  18. depth=1 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = SORB of TASS, CN = Test CA (SM2)
  19. verify return:1
  20. depth=0 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = BSRC of TASS, CN = client sign (SM2)
  21. verify return:1
  22. SSL_accept:SSLv3/TLS read client certificate
  23. ssl_get_algorithm2=f227000008x
  24. SSL_accept:SSLv3/TLS read client key exchange
  25. SSL_accept:SSLv3/TLS read certificate verify
  26. SSL_accept:SSLv3/TLS read change cipher spec
  27. SSL_accept:SSLv3/TLS read finished
  28. SSL_accept:SSLv3/TLS write change cipher spec
  29. SSL_accept:SSLv3/TLS write finished
  30. -----BEGIN SSL SESSION PARAMETERS-----
  31. MIICmAIBAQICAQEEAuATBCAWcAdtfPyMiEJmINUd/e/AmYdNqNTalV1AAbACRSQE
  32. CgQwtuURXPYQpQ7gQIZ3fWRd9QpsP0Zi57oDT1D/X1xVBL3wy9yrr/BOpRw2afsu
  33. 4DH3oQYCBGMw/gSiBAICHCCjggIfMIICGzCCAcGgAwIBAgIJAIVjx+dwZIdmMAoG
  34. CCqBHM9VAYN1MIGCMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
  35. B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
  36. FTATBgNVBAsMDFNPUkIgb2YgVEFTUzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAe
  37. Fw0yMDA2MjAxMDE4MjZaFw0yNDA3MjkxMDE4MjZaMIGGMQswCQYDVQQGEwJDTjEL
  38. MAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcg
  39. Sk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgG
  40. A1UEAwwRY2xpZW50IHNpZ24gKFNNMikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNC
  41. AARV/eII1n2NVqYjwt9r9A5Eh6Z0iG+WUpsw4sGxhfKL0vr0OKcur6DZqjqLDSCr
  42. ZEhU6yuntNtaW+pexPblqXAroxowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAK
  43. BggqgRzPVQGDdQNIADBFAiEAiX+PoCNW/n9SDbv6/o+NyCCV/7kBgunc7w5b7xGm
  44. 4RICIBMDlLjPZE2ACYhu1Wjqph23PfMPMgae4+Gtd7wzFz2UpAYEBAEAAAA=
  45. -----END SSL SESSION PARAMETERS-----
  46. Client certificate
  47. -----BEGIN CERTIFICATE-----
  48. MIICGzCCAcGgAwIBAgIJAIVjx+dwZIdmMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
  49. EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
  50. aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
  51. UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjZaFw0yNDA3
  52. MjkxMDE4MjZaMIGGMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
  53. B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
  54. FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgGA1UEAwwRY2xpZW50IHNpZ24gKFNN
  55. MikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAARV/eII1n2NVqYjwt9r9A5Eh6Z0
  56. iG+WUpsw4sGxhfKL0vr0OKcur6DZqjqLDSCrZEhU6yuntNtaW+pexPblqXAroxow
  57. GDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNIADBFAiEAiX+P
  58. oCNW/n9SDbv6/o+NyCCV/7kBgunc7w5b7xGm4RICIBMDlLjPZE2ACYhu1Wjqph23
  59. PfMPMgae4+Gtd7wzFz2U
  60. -----END CERTIFICATE-----
  61. subject=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=client sign (SM2)
  62. issuer=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  63. 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
  64. CIPHER is SM2-WITH-SMS4-SM3
  65. 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
  1. 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
  2. [GMTLS_DEBUG] set sm2 signing certificate
  3. [GMTLS_DEBUG] set sm2 signing private key
  4. [GMTLS_DEBUG] set sm2 encryption certificate
  5. [GMTLS_DEBUG] set sm2 decryption private key
  6. CONNECTED(00000003)
  7. SSL_connect:before SSL initialization
  8. SSL_connect:SSLv3/TLS write client hello
  9. SSL_connect:SSLv3/TLS write client hello
  10. SSL_connect:SSLv3/TLS read server hello
  11. depth=1 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = SORB of TASS, CN = Test CA (SM2)
  12. verify return:1
  13. depth=0 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = BSRC of TASS, CN = server sign (SM2)
  14. verify return:1
  15. SSL_connect:SSLv3/TLS read server certificate
  16. Z=BCDCCB61AADD790C076DAC60ED09DDD5285A906A4025DD748DA2FB5816464C58
  17. C=00021E3082021A308201C0A0030201020209008563C7E770648765300A06082A811CCF55018375308182310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C534F5242206F6620544153533116301406035504030C0D546573742043412028534D3229301E170D3230303632303130313832365A170D3234303732393130313832365A308185310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C42535243206F6620544153533119301706035504030C1073657276657220656E632028534D32293059301306072A8648CE3D020106082A811CCF5501822D03420004B999853302F02CC522CC4CCA287019E86B901FC24E3CCF9A61B93BB177B28C2CE8E23C5C522DF73C23F7AC36FF688CB2E685A3FA4770103F7C99EFC32D06C11FA31A301830090603551D1304023000300B0603551D0F040403020338300A06082A811CCF550183750348003045022100EC4368F400870BED441817AF4D359BDC61A9EDFDDEE54AB0C185084B450C46B902206E0C3A08BC584590046DC85603CD4E8A51F97D9669B1ACA3E2A3627BE61D49A2
  18. SSL_connect:SSLv3/TLS read server key exchange
  19. SSL_connect:SSLv3/TLS read server certificate request
  20. SSL_connect:SSLv3/TLS read server done
  21. SSL_connect:SSLv3/TLS write client certificate
  22. SSL_connect:SSLv3/TLS write client key exchange
  23. ssl_get_algorithm2=3268600008x
  24. SSL_connect:SSLv3/TLS write certificate verify
  25. SSL_connect:SSLv3/TLS write change cipher spec
  26. SSL_connect:SSLv3/TLS write finished
  27. SSL_connect:SSLv3/TLS write finished
  28. SSL_connect:SSLv3/TLS read change cipher spec
  29. SSL_connect:SSLv3/TLS read finished
  30. ---
  31. Certificate chain
  32. 0 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)
  33. i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  34. -----BEGIN CERTIFICATE-----
  35. MIICGjCCAcGgAwIBAgIJAIVjx+dwZIdkMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
  36. EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
  37. aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
  38. UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjVaFw0yNDA3
  39. MjkxMDE4MjVaMIGGMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
  40. B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
  41. FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgGA1UEAwwRc2VydmVyIHNpZ24gKFNN
  42. MikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAS0lHzt7CkOzCtyf6VwCqoT2PYD
  43. CL/AJrCsHa+6lE8wDZ7DShI2bvfmrpavndEW67CHQOlO0q6/aoEB0PoAgpopoxow
  44. GDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNHADBEAiB06JWp
  45. uxFbGBfvG9juhe2Umu/auI1H2XeMdvDjbOtfuQIgMXT8jewkzq9TR3OPzRTkZCRH
  46. 3H+xKEb8r8JsEEStwaU=
  47. -----END CERTIFICATE-----
  48. 1 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server enc (SM2)
  49. i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  50. -----BEGIN CERTIFICATE-----
  51. MIICGjCCAcCgAwIBAgIJAIVjx+dwZIdlMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
  52. EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
  53. aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
  54. UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjZaFw0yNDA3
  55. MjkxMDE4MjZaMIGFMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
  56. B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
  57. FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEZMBcGA1UEAwwQc2VydmVyIGVuYyAoU00y
  58. KTBZMBMGByqGSM49AgEGCCqBHM9VAYItA0IABLmZhTMC8CzFIsxMyihwGehrkB/C
  59. TjzPmmG5O7F3sows6OI8XFIt9zwj96w2/2iMsuaFo/pHcBA/fJnvwy0GwR+jGjAY
  60. MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgM4MAoGCCqBHM9VAYN1A0gAMEUCIQDsQ2j0
  61. AIcL7UQYF69NNZvcYant/d7lSrDBhQhLRQxGuQIgbgw6CLxYRZAEbchWA81OilH5
  62. fZZpsayj4qNie+YdSaI=
  63. -----END CERTIFICATE-----
  64. 2 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  65. i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  66. -----BEGIN CERTIFICATE-----
  67. MIICWjCCAgCgAwIBAgIJAP5W2mLaOWq5MAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
  68. EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
  69. aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
  70. UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjVaFw0yNDA3
  71. MjkxMDE4MjVaMIGCMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
  72. B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
  73. FTATBgNVBAsMDFNPUkIgb2YgVEFTUzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTBZ
  74. MBMGByqGSM49AgEGCCqBHM9VAYItA0IABArjN7ag+H8D12eqXJpMeTOR9m3sB2RC
  75. ojH7fZPB77SDfHZb9g1lcqUhrug0nw2F8wBMsLfjvsK3wQn/ryi3YvSjXTBbMB0G
  76. A1UdDgQWBBRCcBGiEpd09qSpUlkiGkZ+q+CFbDAfBgNVHSMEGDAWgBRCcBGiEpd0
  77. 9qSpUlkiGkZ+q+CFbDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzP
  78. VQGDdQNIADBFAiBjdylWVsUoTRcHu9DoMHv4lgtYJMf2xHAGLoJUjmbizAIhAOFD
  79. i3EmFVUgGVdgbnztFZcBLxtBzIAh/Q4Q3dm3/MFu
  80. -----END CERTIFICATE-----
  81. ---
  82. Server certificate
  83. subject=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)
  84. issuer=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  85. ---
  86. Acceptable client certificate CA names
  87. /C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  88. Client Certificate Types: RSA sign, DSA sign
  89. ---
  90. SSL handshake has read 2121 bytes and written 2115 bytes
  91. Verification: OK
  92. ---
  93. New, GMTLSv1.1, Cipher is SM2-WITH-SMS4-SM3
  94. Server public key is 256 bit
  95. Secure Renegotiation IS NOT supported
  96. Compression: NONE
  97. Expansion: NONE
  98. No ALPN negotiated
  99. SSL-Session:
  100. Protocol : GMTLSv1.1
  101. Cipher : SM2-WITH-SMS4-SM3
  102. Session-ID: 1670076D7CFC8C88426620D51DFDEFC099874DA8D4DA955D4001B0024524040A
  103. Session-ID-ctx:
  104. Master-Key: B6E5115CF610A50EE04086777D645DF50A6C3F4662E7BA034F50FF5F5C5504BDF0CBDCABAFF04EA51C3669FB2EE031F7
  105. PSK identity: None
  106. PSK identity hint: None
  107. SRP username: None
  108. Start Time: 1664155140
  109. Timeout : 7200 (sec)
  110. Verify return code: 0 (ok)
  111. Extended master secret: no
  112. ---

双证书单向认证 

  • 同时指定签名和加密证书 且 采用双证书单向认证
  • 服务端执行代码
  • 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参数表示打印跟多信息,方便调试
  1. s_server: Cannot open input file gmcrt/2_sign.crt, No such file or directory
  2. s_server: Use -help for summary.
  3. chy-cpabe@ubuntu:~/test_double_ssl/GMSSL双证书demo/sm2Certs$ ls
  4. 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
  5. 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
  6. Using default temp DH parameters
  7. [GMTLS_DEBUG] set sm2 signing certificate
  8. [GMTLS_DEBUG] set sm2 signing private key
  9. [GMTLS_DEBUG] set sm2 encryption certificate
  10. [GMTLS_DEBUG] set sm2 decryption private key
  11. ACCEPT
  12. SSL_accept:before SSL initialization
  13. SSL_accept:before SSL initialization
  14. ssl_get_algorithm2=2b81000008x
  15. SSL_accept:SSLv3/TLS read client hello
  16. SSL_accept:SSLv3/TLS write server hello
  17. SSL_accept:SSLv3/TLS write certificate
  18. SSL_accept:SSLv3/TLS write key exchange
  19. SSL_accept:SSLv3/TLS write server done
  20. SSL_accept:SSLv3/TLS write server done
  21. SSL_accept:SSLv3/TLS read client key exchange
  22. SSL_accept:SSLv3/TLS read change cipher spec
  23. SSL_accept:SSLv3/TLS read finished
  24. SSL_accept:SSLv3/TLS write change cipher spec
  25. SSL_accept:SSLv3/TLS write finished
  26. -----BEGIN SSL SESSION PARAMETERS-----
  27. MHUCAQECAgEBBALgEwQg4tsFtm05e9thEdmOsDjCdEY797x1PAcVaGWd8chdLuoE
  28. MDqjvlXZek3vSlC1q+aYT7NA40D6C7sbR0gNowPIhMfVan396kWxthLUmXIgz3t1
  29. 5qEGAgRjAfsxogQCAhwgpAYEBAEAAAA=
  30. -----END SSL SESSION PARAMETERS-----
  31. 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
  32. CIPHER is SM2-WITH-SMS4-SM3
  33. 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
  1. [GMTLS_DEBUG] set sm2 signing certificate
  2. [GMTLS_DEBUG] set sm2 signing private key
  3. [GMTLS_DEBUG] set sm2 encryption certificate
  4. [GMTLS_DEBUG] set sm2 decryption private key
  5. CONNECTED(00000003)
  6. SSL_connect:before SSL initialization
  7. SSL_connect:SSLv3/TLS write client hello
  8. SSL_connect:SSLv3/TLS write client hello
  9. SSL_connect:SSLv3/TLS read server hello
  10. depth=1 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = SORB of TASS, CN = Test CA (SM2)
  11. verify return:1
  12. depth=0 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = BSRC of TASS, CN = server sign (SM2)
  13. verify return:1
  14. SSL_connect:SSLv3/TLS read server certificate
  15. Z=BCDCCB61AADD790C076DAC60ED09DDD5285A906A4025DD748DA2FB5816464C58
  16. C=00021E3082021A308201C0A0030201020209008563C7E770648765300A06082A811CCF55018375308182310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C534F5242206F6620544153533116301406035504030C0D546573742043412028534D3229301E170D3230303632303130313832365A170D3234303732393130313832365A308185310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C42535243206F6620544153533119301706035504030C1073657276657220656E632028534D32293059301306072A8648CE3D020106082A811CCF5501822D03420004B999853302F02CC522CC4CCA287019E86B901FC24E3CCF9A61B93BB177B28C2CE8E23C5C522DF73C23F7AC36FF688CB2E685A3FA4770103F7C99EFC32D06C11FA31A301830090603551D1304023000300B0603551D0F040403020338300A06082A811CCF550183750348003045022100EC4368F400870BED441817AF4D359BDC61A9EDFDDEE54AB0C185084B450C46B902206E0C3A08BC584590046DC85603CD4E8A51F97D9669B1ACA3E2A3627BE61D49A2
  17. SSL_connect:SSLv3/TLS read server key exchange
  18. SSL_connect:SSLv3/TLS read server done
  19. SSL_connect:SSLv3/TLS write client key exchange
  20. SSL_connect:SSLv3/TLS write change cipher spec
  21. ssl_get_algorithm2=2790100008x
  22. SSL_connect:SSLv3/TLS write finished
  23. SSL_connect:SSLv3/TLS write finished
  24. SSL_connect:SSLv3/TLS read change cipher spec
  25. SSL_connect:SSLv3/TLS read finished
  26. ---
  27. Certificate chain
  28. 0 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)
  29. i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  30. 1 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server enc (SM2)
  31. i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  32. 2 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  33. i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  34. ---
  35. Server certificate
  36. -----BEGIN CERTIFICATE-----
  37. MIICGjCCAcGgAwIBAgIJAIVjx+dwZIdkMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
  38. EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
  39. aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
  40. UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjVaFw0yNDA3
  41. MjkxMDE4MjVaMIGGMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
  42. B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
  43. FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgGA1UEAwwRc2VydmVyIHNpZ24gKFNN
  44. MikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAS0lHzt7CkOzCtyf6VwCqoT2PYD
  45. CL/AJrCsHa+6lE8wDZ7DShI2bvfmrpavndEW67CHQOlO0q6/aoEB0PoAgpopoxow
  46. GDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNHADBEAiB06JWp
  47. uxFbGBfvG9juhe2Umu/auI1H2XeMdvDjbOtfuQIgMXT8jewkzq9TR3OPzRTkZCRH
  48. 3H+xKEb8r8JsEEStwaU=
  49. -----END CERTIFICATE-----
  50. subject=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)
  51. issuer=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  52. ---
  53. No client certificate CA names sent
  54. ---
  55. SSL handshake has read 1973 bytes and written 320 bytes
  56. Verification: OK
  57. ---
  58. New, GMTLSv1.1, Cipher is SM2-WITH-SMS4-SM3
  59. Server public key is 256 bit
  60. Secure Renegotiation IS NOT supported
  61. Compression: NONE
  62. Expansion: NONE
  63. No ALPN negotiated
  64. SSL-Session:
  65. Protocol : GMTLSv1.1
  66. Cipher : SM2-WITH-SMS4-SM3
  67. Session-ID: E24D8195A9D25F9A6B877C63A85979492FA5199E58FA512A95915E33BA7A418B
  68. Session-ID-ctx:
  69. Master-Key: 2ED26139965074A55F65D011A370DF7A4672A0FC7BBB4A0ED991DCD55A6231E92B5A09225BFE9F1ABD0546F1F75885A2
  70. PSK identity: None
  71. PSK identity hint: None
  72. SRP username: None
  73. Start Time: 1661073328
  74. Timeout : 7200 (sec)
  75. Verify return code: 0 (ok)
  76. Extended master secret: no
  77. ---
  • 客户端命令
  • 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
  1. 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
  2. [GMTLS_DEBUG] set sm2 signing certificate
  3. [GMTLS_DEBUG] set sm2 signing private key
  4. [GMTLS_DEBUG] set sm2 encryption certificate
  5. [GMTLS_DEBUG] set sm2 decryption private key
  6. CONNECTED(00000003)
  7. SSL_connect:before SSL initialization
  8. SSL_connect:SSLv3/TLS write client hello
  9. SSL_connect:SSLv3/TLS write client hello
  10. SSL_connect:SSLv3/TLS read server hello
  11. depth=1 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = SORB of TASS, CN = Test CA (SM2)
  12. verify return:1
  13. depth=0 C = CN, ST = BJ, L = HaiDian, O = Beijing JNTA Technology LTD., OU = BSRC of TASS, CN = server sign (SM2)
  14. verify return:1
  15. SSL_connect:SSLv3/TLS read server certificate
  16. Z=BCDCCB61AADD790C076DAC60ED09DDD5285A906A4025DD748DA2FB5816464C58
  17. C=00021E3082021A308201C0A0030201020209008563C7E770648765300A06082A811CCF55018375308182310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C534F5242206F6620544153533116301406035504030C0D546573742043412028534D3229301E170D3230303632303130313832365A170D3234303732393130313832365A308185310B300906035504061302434E310B300906035504080C02424A3110300E06035504070C074861694469616E31253023060355040A0C1C4265696A696E67204A4E544120546563686E6F6C6F6779204C54442E31153013060355040B0C0C42535243206F6620544153533119301706035504030C1073657276657220656E632028534D32293059301306072A8648CE3D020106082A811CCF5501822D03420004B999853302F02CC522CC4CCA287019E86B901FC24E3CCF9A61B93BB177B28C2CE8E23C5C522DF73C23F7AC36FF688CB2E685A3FA4770103F7C99EFC32D06C11FA31A301830090603551D1304023000300B0603551D0F040403020338300A06082A811CCF550183750348003045022100EC4368F400870BED441817AF4D359BDC61A9EDFDDEE54AB0C185084B450C46B902206E0C3A08BC584590046DC85603CD4E8A51F97D9669B1ACA3E2A3627BE61D49A2
  18. SSL_connect:SSLv3/TLS read server key exchange
  19. SSL_connect:SSLv3/TLS read server certificate request
  20. SSL_connect:SSLv3/TLS read server done
  21. SSL_connect:SSLv3/TLS write client certificate
  22. SSL_connect:SSLv3/TLS write client key exchange
  23. ssl_get_algorithm2=3c3f900008x
  24. SSL_connect:SSLv3/TLS write certificate verify
  25. SSL_connect:SSLv3/TLS write change cipher spec
  26. SSL_connect:SSLv3/TLS write finished
  27. SSL3 alert read:fatal:decrypt error
  28. SSL_connect:error in SSLv3/TLS write finished
  29. 140016949239808:error:1409441B:SSL routines:ssl3_read_bytes:tlsv1 alert decrypt error:ssl/record/rec_layer_s3.c:1385:SSL alert number 51
  30. ---
  31. Certificate chain
  32. 0 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)
  33. i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  34. 1 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server enc (SM2)
  35. i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  36. 2 s:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  37. i:/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  38. ---
  39. Server certificate
  40. -----BEGIN CERTIFICATE-----
  41. MIICGjCCAcGgAwIBAgIJAIVjx+dwZIdkMAoGCCqBHM9VAYN1MIGCMQswCQYDVQQG
  42. EwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcMB0hhaURpYW4xJTAjBgNVBAoMHEJl
  43. aWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4xFTATBgNVBAsMDFNPUkIgb2YgVEFT
  44. UzEWMBQGA1UEAwwNVGVzdCBDQSAoU00yKTAeFw0yMDA2MjAxMDE4MjVaFw0yNDA3
  45. MjkxMDE4MjVaMIGGMQswCQYDVQQGEwJDTjELMAkGA1UECAwCQkoxEDAOBgNVBAcM
  46. B0hhaURpYW4xJTAjBgNVBAoMHEJlaWppbmcgSk5UQSBUZWNobm9sb2d5IExURC4x
  47. FTATBgNVBAsMDEJTUkMgb2YgVEFTUzEaMBgGA1UEAwwRc2VydmVyIHNpZ24gKFNN
  48. MikwWTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAS0lHzt7CkOzCtyf6VwCqoT2PYD
  49. CL/AJrCsHa+6lE8wDZ7DShI2bvfmrpavndEW67CHQOlO0q6/aoEB0PoAgpopoxow
  50. GDAJBgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNHADBEAiB06JWp
  51. uxFbGBfvG9juhe2Umu/auI1H2XeMdvDjbOtfuQIgMXT8jewkzq9TR3OPzRTkZCRH
  52. 3H+xKEb8r8JsEEStwaU=
  53. -----END CERTIFICATE-----
  54. subject=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=BSRC of TASS/CN=server sign (SM2)
  55. issuer=/C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  56. ---
  57. Acceptable client certificate CA names
  58. /C=CN/ST=BJ/L=HaiDian/O=Beijing JNTA Technology LTD./OU=SORB of TASS/CN=Test CA (SM2)
  59. Client Certificate Types: RSA sign, DSA sign
  60. ---
  61. SSL handshake has read 2037 bytes and written 2116 bytes
  62. Verification: OK
  63. ---
  64. New, GMTLSv1.1, Cipher is SM2-WITH-SMS4-SM3
  65. Server public key is 256 bit
  66. Secure Renegotiation IS NOT supported
  67. Compression: NONE
  68. Expansion: NONE
  69. No ALPN negotiated
  70. SSL-Session:
  71. Protocol : GMTLSv1.1
  72. Cipher : SM2-WITH-SMS4-SM3
  73. Session-ID: 12664AE82CE989580C27B14AFF7487B19FF1C159C94291A0B76AA5F80D28317F
  74. Session-ID-ctx:
  75. Master-Key: AD4D5164B7F54B9FA1F74A7A569C6B6E75CFD96967AB7519658C33E9C6FB8851EBCF1B10E175E736E9C7127E5FA8D32D
  76. PSK identity: None
  77. PSK identity hint: None
  78. SRP username: None
  79. Start Time: 1661074697
  80. Timeout : 7200 (sec)
  81. Verify return code: 0 (ok)
  82. Extended master secret: no
  83. ---

双证书双向认证-代码实现

 参考链接

 注意事项

  • 基于TASSL开源项目中的Tassl_demo/mk_tls_cert 下的 SM2certgen.sh 脚本,共生成 15 个 PEM 文件,即根证书、服务端和客户端的签名和加密证书
  • 上述参考链接里面的下面这句话是错误的,服务端都不验证客户端身份了,还叫双向认证嘛??
  • 修改后代码如下
  1. // 是否要求校验对方证书 此处不验证客户端身份所以为: SSL_VERIFY_NONE
  2. SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);

 服务端代码

  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cerrno>
  4. #include <cstring>
  5. #include <netinet/in.h>
  6. #include <sys/socket.h>
  7. #include <unistd.h>
  8. #include <arpa/inet.h>
  9. #include <openssl/ssl.h>
  10. #include <openssl/err.h>
  11. #define MAXBUF 1500
  12. //#define CA_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CA.cert.pem"
  13. //#define SIGN_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/SS.cert.pem"
  14. //#define SIGN_KEY_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/SS.key.pem"
  15. //#define ENCODE_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/SE.cert.pem"
  16. //#define ENCODE_KEY_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/SE.key.pem"
  17. #define CA_CERT_FILE "/home/chy-cpabe/tmp/second/rootcert.pem"
  18. #define SIGN_CERT_FILE "/home/chy-cpabe/tmp/second/sign.pem"
  19. #define SIGN_KEY_FILE "/home/chy-cpabe/tmp/second/sign.key"
  20. #define ENCODE_CERT_FILE "/home/chy-cpabe/tmp/second/encrypt.pem"
  21. #define ENCODE_KEY_FILE "/home/chy-cpabe/tmp/second/encrypt.key"
  22. void ShowCerts(SSL * ssl)
  23. {
  24. X509 *cert;
  25. char *line;
  26. cert = SSL_get_peer_certificate(ssl);
  27. // SSL_get_verify_result()是重点,SSL_CTX_set_verify()只是配置启不启用并没有执行认证,调用该函数才会真证进行证书认证
  28. // 如果验证不通过,那么程序抛出异常中止连接
  29. if(SSL_get_verify_result(ssl) == X509_V_OK){
  30. printf("证书验证通过\n");
  31. }
  32. if (cert != nullptr) {
  33. printf("数字证书信息:\n");
  34. line = X509_NAME_oneline(X509_get_subject_name(cert), nullptr, 0);
  35. printf("证书: %s\n", line);
  36. free(line);
  37. line = X509_NAME_oneline(X509_get_issuer_name(cert), nullptr, 0);
  38. printf("颁发者: %s\n", line);
  39. free(line);
  40. X509_free(cert);
  41. } else
  42. printf("无证书信息!\n");
  43. }
  44. int main(int argc, char **argv) {
  45. int listen_fd = -1; /* TCP监听套接字 */
  46. int accept_fd = -1; /* 已连接TCP套接字 */
  47. struct sockaddr_in server_addr, client_addr;
  48. bzero(&server_addr, sizeof(server_addr));
  49. SSL_CTX *ctx = nullptr; /* SSL会话环境 */
  50. SSL *ssl = nullptr; /* SSL安全套接字 */
  51. socklen_t len;
  52. char buf[MAXBUF]={0}; /* 服务器接收数据buffer */
  53. if( 3!=argc )
  54. {
  55. printf("argcment wrong:ip port\n");
  56. }
  57. SSL_library_init(); /* SSL 库初始化 */
  58. SSLeay_add_ssl_algorithms();
  59. OpenSSL_add_all_algorithms(); /* 载入所有 SSL 算法 */
  60. SSL_load_error_strings(); /* 载入所有 SSL 错误消息 */
  61. // ERR_load_BIO_strings();
  62. //TCP服务器:创建、绑定、监听
  63. if ((listen_fd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
  64. perror("socket create wrong\n");
  65. exit(1);
  66. } else
  67. printf("socket created\n");
  68. server_addr.sin_family = PF_INET;
  69. server_addr.sin_port = htons(atoi(argv[2]));
  70. server_addr.sin_addr.s_addr = inet_addr(argv[1]);;
  71. if (bind(listen_fd, (struct sockaddr *) &server_addr, sizeof(struct sockaddr))
  72. == -1) {
  73. perror("bind wrong\n");
  74. exit(1);
  75. } else
  76. printf("binded success\n");
  77. int lisnum = 2;
  78. do{
  79. //使用SSL_CTX_new()创建会话环境,建立连接时要使用协议由TLS_server_method()来定。如果这一步出错,需要查看错误栈来查看原因
  80. if(nullptr == (ctx = SSL_CTX_new( GMTLS_server_method()))) //using sm3, TLSv1_2_method
  81. {
  82. ERR_print_errors_fp(stderr);
  83. break;
  84. }
  85. // SSL_CTX_set_security_level(ctx,0);
  86. // 双向验证
  87. // SSL_VERIFY_PEER---要求对证书进行认证,没有证书也会放行
  88. // SSL_VERIFY_FAIL_IF_NO_PEER_CERT---要求客户端需要提供证书,但验证发现单独使用没有证书也会放行
  89. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
  90. // 设置信任根证书
  91. if(SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, nullptr) != 1)
  92. {
  93. printf("SSL_CTX_load_verify_locations error\n");
  94. ERR_print_errors_fp(stderr);
  95. break;
  96. }
  97. // 签名证书和对应私钥
  98. if( 0>=SSL_CTX_use_certificate_file(ctx, SIGN_CERT_FILE, SSL_FILETYPE_PEM/*SSL_FILETYPE_ASN1*/) ) /* 为SSL会话加载用户证书 */
  99. {
  100. printf("SSL_CTX_use_certificate_file error!\n");
  101. ERR_print_errors_fp(stderr);
  102. break;
  103. }
  104. if( 0>=SSL_CTX_use_PrivateKey_file(ctx, SIGN_KEY_FILE, SSL_FILETYPE_PEM/*SSL_FILETYPE_ASN1*/) ) /* 为SSL会话加载用户私钥 */
  105. {
  106. printf("SSL_CTX_use_PrivateKey_file error!\n");
  107. ERR_print_errors_fp(stderr);
  108. break;
  109. }
  110. // 加密证书和对应私钥
  111. if(SSL_CTX_use_certificate_file(ctx, ENCODE_CERT_FILE, SSL_FILETYPE_PEM) <= 0)
  112. {
  113. printf("SSL_CTX_use_certificate_file error!\n");
  114. ERR_print_errors_fp(stderr);
  115. return -1;
  116. }
  117. if(SSL_CTX_use_PrivateKey_file(ctx, ENCODE_KEY_FILE, SSL_FILETYPE_PEM) <= 0)
  118. {
  119. printf("SSL_CTX_use_PrivateKey_file error!\n");
  120. ERR_print_errors_fp(stderr);
  121. return -1;
  122. }
  123. /* 检查用户私钥是否正确 */
  124. if(!SSL_CTX_check_private_key(ctx)) /* 验证私钥和证书是否相符 */
  125. {
  126. printf("SSL_CTX_check_private_key error!\n");
  127. ERR_print_errors_fp(stderr);
  128. break;
  129. }
  130. if (listen(listen_fd, lisnum) == -1) {
  131. perror("listen wrong\n");
  132. exit(1);
  133. } else
  134. printf("begin listen\n");
  135. len = sizeof(struct sockaddr);
  136. /* 等待客户端连上来 */
  137. if ((accept_fd = accept(listen_fd, (struct sockaddr *) &client_addr, &len))
  138. == -1) {
  139. perror("accept wrong\n");
  140. exit(errno);
  141. } else{
  142. printf("server: got connection from %s, port %d, socket %d\n",
  143. inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port),
  144. accept_fd);
  145. }
  146. ssl = SSL_new(ctx); /* 基于 ctx 产生一个新的 SSL */
  147. SSL_set_fd(ssl, accept_fd); /* 将连接用户的 socket 加入到 SSL */
  148. /* 建立 SSL 连接 */
  149. if (SSL_accept(ssl) == -1) {
  150. perror("accept wrong\n");
  151. SSL_shutdown(ssl);
  152. SSL_free(ssl);
  153. ssl= nullptr;
  154. close(accept_fd);
  155. accept_fd=-1;
  156. break;
  157. }
  158. ShowCerts(ssl);
  159. /* 开始处理每个新连接上的数据收发 */
  160. bzero(buf, MAXBUF + 1);
  161. strcpy(buf, "server->client");
  162. /* 发消息给客户端 */
  163. len = SSL_write(ssl, buf, strlen(buf));
  164. if (len <= 0) {
  165. printf("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n", buf, errno,
  166. strerror(errno));
  167. goto finish;
  168. } else
  169. printf("消息'%s'发送成功,共发送了%d个字节!\n", buf, len);
  170. bzero(buf, MAXBUF + 1);
  171. /* 接收客户端的消息 */
  172. len = SSL_read(ssl, buf, MAXBUF);
  173. if (len > 0)
  174. printf("接收消息成功:'%s',共%d个字节的数据\n", buf, len);
  175. else
  176. printf("消息接收失败!错误代码是%d,错误信息是'%s'\n",
  177. errno, strerror(errno));
  178. /* 处理每个新连接上的数据收发结束 */
  179. finish:
  180. /* 关闭 SSL 连接 */
  181. SSL_shutdown(ssl);
  182. /* 释放 SSL */
  183. SSL_free(ssl);
  184. ssl = nullptr;
  185. /* 关闭 socket */
  186. close(accept_fd);
  187. accept_fd = -1;
  188. }while(1);
  189. /* 关闭监听的 socket */
  190. close(listen_fd);
  191. listen_fd = -1;
  192. /* 释放 CTX */
  193. SSL_CTX_free(ctx);
  194. ctx = nullptr;
  195. return 0;
  196. }

客户端代码

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cerrno>
  4. #include <sys/socket.h>
  5. #include <cstdlib>
  6. #include <netinet/in.h>
  7. #include <arpa/inet.h>
  8. #include <unistd.h>
  9. #include <openssl/ssl.h>
  10. #include <openssl/err.h>
  11. #define MAXBUF 1024
  12. //#define CA_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CA.cert.pem"
  13. //#define CS_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CS.cert.pem"
  14. //#define CS_KEY_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CS.key.pem"
  15. //#define CE_CERT_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CE.cert.pem"
  16. //#define CE_KEY_FILE "/home/chy-cpabe/GMSSL_certificate/sm2Certs/CE.key.pem"
  17. #define CA_CERT_FILE "/home/chy-cpabe/tmp/first/rootcert.pem"
  18. #define CS_CERT_FILE "/home/chy-cpabe/tmp/first/sign.pem"
  19. #define CS_KEY_FILE "/home/chy-cpabe/tmp/first/sign.key"
  20. #define CE_CERT_FILE "/home/chy-cpabe/tmp/first/encrypt.pem"
  21. #define CE_KEY_FILE "/home/chy-cpabe/tmp/first/encrypt.key"
  22. void ShowCerts(SSL * ssl)
  23. {
  24. X509 *cert;
  25. char *line;
  26. cert = SSL_get_peer_certificate(ssl);
  27. // SSL_get_verify_result()是重点,SSL_CTX_set_verify()只是配置启不启用并没有执行认证,调用该函数才会真证进行证书认证
  28. // 如果验证不通过,那么程序抛出异常中止连接
  29. if(SSL_get_verify_result(ssl) == X509_V_OK){
  30. printf("证书验证通过\n");
  31. }
  32. if (cert != nullptr) {
  33. printf("数字证书信息:\n");
  34. line = X509_NAME_oneline(X509_get_subject_name(cert), nullptr, 0);
  35. printf("证书: %s\n", line);
  36. free(line);
  37. line = X509_NAME_oneline(X509_get_issuer_name(cert), nullptr, 0);
  38. printf("颁发者: %s\n", line);
  39. free(line);
  40. X509_free(cert);
  41. } else
  42. printf("无证书信息!\n");
  43. }
  44. static void PrintData(char *p, char *buf,int len,char *filename)
  45. {
  46. char *name=p;
  47. printf("%s[%d]:\n",p,len);
  48. for (p=buf; p && p++-buf<len;)
  49. printf("%02x%c",(unsigned char)p[-1],(!((p-buf)%16) || p-buf==len)?'\n':' ');
  50. // if (filename) FileWrite(name,buf,len,filename);
  51. }
  52. int main(int argc, char **argv)
  53. {
  54. int sock_fd = -1; /* TCP套接字 */
  55. int len = 0; /* SSL会话环境 */
  56. SSL *ssl = nullptr; /* SSL安全套接字 */
  57. struct sockaddr_in ser_addr; /* 服务器地址 */
  58. bzero(&ser_addr, sizeof(ser_addr));
  59. SSL_CTX *ctx = nullptr;
  60. char buffer[MAXBUF + 1];
  61. if( argc != 3 )
  62. {
  63. printf("argcment wrong:ip port content\n");
  64. exit(0);
  65. }
  66. /* SSL 库初始化,参看 ssl-server.c 代码 */
  67. SSL_library_init();
  68. SSLeay_add_ssl_algorithms();
  69. OpenSSL_add_all_algorithms();
  70. SSL_load_error_strings();
  71. // ERR_load_BIO_strings();
  72. do{
  73. /* 申请SSL会话环境 */
  74. if( nullptr==(ctx=SSL_CTX_new(GMTLS_client_method())) ) //使用SSL_CTX_new()创建会话环境,建立连接时要使用协议由TLS_client_method()来定,服务器由对应的TLS_server_method()来定。如果这一步出错,需要查看错误栈来查看原因
  75. {
  76. printf("SSL_CTX_new error!\n");
  77. ERR_print_errors_fp(stderr);
  78. break;
  79. }
  80. // 双向验证
  81. // SSL_VERIFY_PEER---要求对证书进行认证,没有证书也会放行
  82. // SSL_VERIFY_FAIL_IF_NO_PEER_CERT---要求客户端需要提供证书,但验证发现单独使用没有证书也会放行
  83. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr);
  84. // if(SSL_CTX_set_cipher_list(ctx, "ECC-SM2-WITH-SM4-SM3") <= 0){
  85. // printf("SSL_CTX_set_cipher_list error!\n");
  86. // ERR_print_errors_fp(stderr);
  87. // exit(1);
  88. // }
  89. // 设置信任根证书
  90. if(SSL_CTX_load_verify_locations(ctx, CA_CERT_FILE, nullptr) != 1)
  91. {
  92. printf("SSL_CTX_load_verify_locations error!\n");
  93. ERR_print_errors_fp(stderr);
  94. exit(1);
  95. }
  96. // 签名证书和对应私钥
  97. if (SSL_CTX_use_certificate_file(ctx, CS_CERT_FILE, SSL_FILETYPE_PEM) <= 0)
  98. {
  99. printf("SSL_CTX_use_certificate_file error!\n");
  100. ERR_print_errors_fp(stderr);
  101. exit(1);
  102. }
  103. if (SSL_CTX_use_PrivateKey_file(ctx, CS_KEY_FILE, SSL_FILETYPE_PEM) <= 0)
  104. {
  105. printf("SSL_CTX_use_PrivateKey_file error!\n");
  106. ERR_print_errors_fp(stderr);
  107. exit(1);
  108. }
  109. // 加密证书和对应私钥
  110. if(SSL_CTX_use_certificate_file(ctx, CE_CERT_FILE, SSL_FILETYPE_PEM) <= 0)
  111. {
  112. printf("SSL_CTX_use_certificate_file error!\n");
  113. ERR_print_errors_fp(stderr);
  114. return -1;
  115. }
  116. if(SSL_CTX_use_PrivateKey_file(ctx, CE_KEY_FILE, SSL_FILETYPE_PEM) <= 0)
  117. {
  118. printf("SSL_CTX_use_PrivateKey_file error!\n");
  119. ERR_print_errors_fp(stderr);
  120. return -1;
  121. }
  122. //判定私钥是否正确
  123. if (!SSL_CTX_check_private_key(ctx)) {
  124. printf("SSL_CTX_check_private_key error!\n");
  125. ERR_print_errors_fp(stderr);
  126. exit(1);
  127. }
  128. // SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
  129. /* 创建一个 socket 用于 tcp 通信 */
  130. if(-1==(sock_fd=socket(AF_INET, SOCK_STREAM, 0)) )
  131. {
  132. printf("creat socket wrong\n");
  133. break;
  134. }
  135. printf("socket created\n");
  136. /* 初始化服务器端(对方)的地址和端口信息 */
  137. ser_addr.sin_family = AF_INET;
  138. ser_addr.sin_port = htons(atoi(argv[2]));
  139. ser_addr.sin_addr.s_addr = inet_addr(argv[1]);
  140. printf("address created\n");
  141. //建立连接
  142. if( -1==(connect(sock_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr))) )
  143. {
  144. printf("connect wrong\n");
  145. break;
  146. }
  147. printf("server connected\n");
  148. /* 基于 ctx 产生一个新的 SSL */
  149. ssl = SSL_new(ctx);
  150. SSL_set_fd(ssl, sock_fd);
  151. /* 建立 SSL 连接 */
  152. if (SSL_connect(ssl) == -1)
  153. ERR_print_errors_fp(stderr);
  154. else {
  155. printf("The relevant information is as follows:\n");
  156. printf("-->ssl version %s\n",SSL_get_version(ssl));
  157. printf("-->ssleay version %s\n",SSLeay_version(0));
  158. printf("-->Connected with %s encryption\n", SSL_get_cipher(ssl));
  159. ShowCerts(ssl);
  160. }
  161. //导出key和salt
  162. unsigned char buf[16];
  163. int err = -1;
  164. err = SSL_export_keying_material(ssl, buf, 16, nullptr,0, nullptr, 0, 1);
  165. if(err != 1){
  166. printf("SSL_export_keying_material error,err=%d\n",err);
  167. }else{
  168. PrintData("SSL_export_keying_material", (char*)buf, 16, nullptr);
  169. }
  170. /* 接收对方发过来的消息,最多接收 MAXBUF 个字节 */
  171. bzero(buffer, MAXBUF + 1);
  172. /* 接收服务器来的消息 */
  173. len = SSL_read(ssl, buffer, MAXBUF);
  174. if (len > 0)
  175. printf("接收消息成功:'%s',共%d个字节的数据\n",
  176. buffer, len);
  177. else {
  178. printf
  179. ("消息接收失败!错误代码是%d,错误信息是'%s'\n",
  180. errno, strerror(errno));
  181. goto finish;
  182. }
  183. bzero(buffer, MAXBUF + 1);
  184. strcpy(buffer, "from client->server");
  185. /* 发消息给服务器 */
  186. len = SSL_write(ssl, buffer, strlen(buffer));
  187. if (len < 0)
  188. printf
  189. ("消息'%s'发送失败!错误代码是%d,错误信息是'%s'\n",
  190. buffer, errno, strerror(errno));
  191. else
  192. printf("消息'%s'发送成功,共发送了%d个字节!\n",
  193. buffer, len);
  194. /* 处理每个新连接上的数据收发结束 */
  195. finish:
  196. /* 关闭 SSL 连接 */
  197. SSL_shutdown(ssl);
  198. /* 释放 SSL */
  199. SSL_free(ssl);
  200. ssl = nullptr;
  201. }while(0);
  202. /* 关闭socket */
  203. close(sock_fd);
  204. sock_fd = -1;
  205. /* 释放 CTX */
  206. SSL_CTX_free(ctx);
  207. ctx = nullptr;
  208. return 0;
  209. }

注意事项

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/118252
推荐阅读
相关标签
  

闽ICP备14008679号