主页

引言

TLS作为保证网络通信安全的关键技术和基石被广泛应用,但目前主流国内外网站仍然使用国际TLS协议,即:TLS1.2TLS1.3。随着国内《网络安全法》、《密码法》和《数据安全法》等法律法规的颁布和实施,国密TLS在国内关键领域也逐渐被应用。

支持国密TLS具有以下重要意义:

  • 数据保护:国密TLS使用了国密算法,减少了对国际密码算法的依赖,降低了使用国际算法可能造成的安全隐患
  • 自主可控:技术自主可控,降低了对国际技术的依赖,提高国内密码技术的自主研发能力
  • 合规要求:在某些行业,使用国际算法不符合法律法规和监管要求

国密标准GB/T 39786网络和通信安全层面的密码应用提出了明确的技术要求,涉及通信主体的各个要素, 都需要进行密码技术改造,支持国密TLS。这也是密评中对于“网络和通信安全“的基本技术要求。

本文内容组织如下:

  • 简介
  • 协议原理
  • wireshark抓包分析
  • 总结&参考文献

简介

国密TLS,又称GMTLS1.1,涉及的主要标准有:

  • 《信息安全技术 传输层密码协议(TLCP)》,即GB/T 38636-2020
  • 《SSL VPN技术规范》,即GM/T 0024-2014
  • 上述协议关联标准:如数字证书标准GB/T 20518, SM2密码算法标准GB/T 35275

注:《SSL VPN技术规范》作为行业标准,部分内容已上升为《信息安全技术 传输层密码协议(TLCP)》国密标准, 后文中介绍的内容以后者为准。

GMTLS1.1中的1.1代表国密TLS的版本号: 0x0101。众所周知,目前TLS协议支持的版本:

	VersionTLS10 = 0x0301
VersionTLS11 = 0x0302
VersionTLS12 = 0x0303
VersionTLS13 = 0x0304

目前主流的TLS软件程序实现中,通信实体在建立TLS连接时,会优先协商使用最大版本号TLS协议 (版本号越大意味着安全性越高、性能越好),因此VersionGMSSL = 0x0101 版本号的设定增加了软件支持的复杂度,这也是阻碍GMTLS1.1广泛应用的一个重要原因。(估计国密TLS协议制定者都是一帮学术大佬,实践经验不足)

GMTLS1.1中相关的密码套件(图片来自GB/T 38636-2020):

从图中可以了解到GMTLS1.1:

  • 密钥交换算法包含ECDHE、ECC、IBSDH、IBC以及RSA,其中IBC和IBSDH主要涉及到SM9标识密码算法
  • 加密算法只有SM4,加密模式涉及两种方式:CBCGCM
  • 校验算法/哈希算法包含:SM3和SHA256

注:从上图中我们还可以了解到,在GMTLS1.1支持的套件中,包含了国际算法RSA和SHA256,这里从公开文献中未找到具体原因,大胆猜测主要是为了:

  • 支持国际知名CA机构颁发的数字证书
  • 作为一种切换到全国密TLS过度

协议原理

GMTLS1.1协议主要参考了TLS1.1,并借鉴了TLS1.2的部分内容。在关键流程上基本一致,只是在密码算法使用上用国密算法国际算法j进行了替换(从这里可以看到,GMTLS1.1在协议原理上并未有太大创新,基本照搬)。 这里附一张GMTLS1.1协议流程图:

由于协议流程与TLS1.2一致,这里不再赘述,可以参考之前的文章:《TLS原理与实践(一)》

Wireshark抓包分析

下面我们通过示例代码wireshark抓包分析来详细介绍GMTLS1.1协议流程,后文Wireshark抓包分析主要介绍与TLS1.2不同的地方。

在示例中,涉及到的工具有:

practical-crypto介绍

# 下载示例代码
➜ practical-crypto git:(master) git clone https://github.com/warm3snow/practical-crypto.git # 查看示例代码目录结构
➜ practical-crypto git:(master) tree tls
tls
├── gmtls
│   └── gmtls1_1.go # 使用国密TLS的https服务
├── notls #无tls保护http服务
│   └── notls.go
├── readme.md #帮助文档
├── tls1.2 # 使用tls1.2协议的http服务
│   └── tls1_2.go
├── tls1.3 # 使用tls1.3协议的http服务
│   └── tls1.3.go
└── tlsclient.go # http客户端,可以发起http或https请求 # 查看国密证书生成脚本
➜ practical-crypto git:(master) cat openssl/generate_sm2_cert.sh
#!/bin/sh
# 1. 设置证书主体subject
SUBJ="/C=CN/ST=BeiJing/L=BeiJing/O=warm3snow/OU=Server/CN=localhost" # 2. 生成签名证书 (openssl 1.1.x以上版本支持sm2, 或者tassl、gmssl)
gmssl ecparam -genkey -name SM2 -text -out ./gmcerts/server_sign.key
gmssl req -new -key ./gmcerts/server_sign.key -out ./gmcerts/server.csr -subj $SUBJ
gmssl x509 -req -days 3650 -sm3 -in ./gmcerts/server.csr -signkey ./gmcerts/server_sign.key -out ./gmcerts/server_sign.crt \
-extfile ./openssl.cnf -extensions v3_req_sign # 3. 生成加密证书
gmssl ecparam -genkey -name SM2 -text -out ./gmcerts/server_enc.key
gmssl req -new -key ./gmcerts/server_enc.key -out ./gmcerts/server.csr -subj $SUBJ
gmssl x509 -req -days 3650 -sm3 -in ./gmcerts/server.csr -signkey ./gmcerts/server_enc.key -out ./gmcerts/server_enc.crt \
-extfile ./openssl.cnf -extensions v3_req_enc

注意在支持gmtls1.1的https服务中,引用了第三方实现包(golang语言实现), 主要代码如下:

import (
tls "github.com/warm3snow/gmsm/gmtls" //1. 支持GMTLS1.1的tls协议实现包
"log"
"net/http"
) func HelloHandler(w http.ResponseWriter, r *http.Request) { // 2. 服务端hello响应实现函数
log.Printf("Received connection: %s", r.RemoteAddr)
w.Write([]byte("Hello, world!"))
} func main() {
// 设置handler
mux := http.NewServeMux()
mux.HandleFunc("/", HelloHandler) // 3. 加载服务端签名证书和签名私钥
signKeyPair, err := tls.LoadX509KeyPair("../../openssl/gmcerts/server_sign.crt", "../../openssl/gmcerts/server_sign.key")
if err != nil {
log.Fatalf("LoadX509KeyPair: %v", err)
} // 4. 加载服务端加密证书和加密私钥
encKeyPair, err := tls.LoadX509KeyPair("../../openssl/gmcerts/server_enc.crt", "../../openssl/gmcerts/server_enc.key")
if err != nil {
log.Fatalf("LoadX509KeyPair: %v", err)
}
// 5. 设置GMTLS1.1配置项
tlsCfg := &tls.Config{
GMSupport: tls.NewGMSupport(),
Certificates: []tls.Certificate{signKeyPair, encKeyPair},
MaxVersion: tls.VersionTLS12,
}
ln, err := tls.Listen("tcp", ":8443", tlsCfg)
if err != nil {
log.Fatalf("Listen: %v", err)
} // 6. 其中https服务
err = http.Serve(ln, mux)
if err != nil {
log.Fatalf("Serve: %v", err)
}
}

从上述代码中,我们可以看到GMTLS1.1需要设置两个证书,一个是签名证书,用于签名验证;一个是加密证书,用于数据加密(这里指的是握手过程中涉及到的加密)。这种双证书体系使得证书的这两种功能(加密和签名验证)能够使用不同证书来单独处理,提高了安全性。

启动服务并进行抓包

  • 启动https服务,并使用tlsClient客户端发送请求

  • 打开wireshark并进行抓包设置

从左上角图的最后输出我们可以看到,GMTLS1.1协议执行完成,服务端最终返回了Hello world!消息。

概览图

从概览图中,我们可以了解到:

  • 客户端和服务端通信使用了GMTLSv1协议,即GMTLS1.1
  • GMTLS1.1握手协议发送的消息类型与TLS1.2完全一致
  • 握手完成后,进行了应用数据Application Data通信

Client Hello消息

从Client Hello消息中,我们可以看出:

  • 协议版本号:客户端使用的协议版本号为GMTLS(0x0101)
  • 加密套件:客户端支持的GMTLS加密套件有4个, 并不是标准里面的12个(这与测试程序引用的gmtls实现包有关系, 目前仅支持4个国密tls加密套件),分别为:
          Cipher Suite: ECC_SM4_CBC_SM3 (0xe013)
Cipher Suite: ECC_SM4_GCM_SM3 (0xe053)
Cipher Suite: ECDHE_SM4_CBC_SM3 (0xe011)
Cipher Suite: ECDHE_SM4_GCM_SM3 (0xe051)

Server Hello消息

服务端发送ServerHello消息后,紧接着发送了Certificate消息。

从上图我们可以了解到:

  • 服务端TLS版本号:服务端和客户端握手过程中使用了GMTLS1.1协议
  • 协商使用的加密套件:服务端和客户端最终协商使用了ECC_SM4_CBC_SM3加密套件。注意我们在测试用例中并未指定使用的加密套件,服务端和客户端默认协商使用排在加密套件列表最前端的一个,参考上文Client Hello发送的加密套件列表。
  • 服务端返回的签名证书,从图中可以看出服务端返回了我们在启动服务时在代码中设置的签名证书
  • 服务端返回的加密证书,从图中可以看出服务端返回了我们在启动服务时在代码中设置的加密证书

服务端签名证书:

  • Wireshark抓包详情(Certificate消息)

  • practical-crypto测试程序服务端使用的签名证书

从上面两张图可以看出:抓包显示证书的KeyUage - digitalSignature字段,和服务端启动设置证书的X509v3 Key Usage - Digital Signature字段对应,都为签名证书。(实际上我们这里想要说明的是发送的签名证书无误,由于签名证书和加密证书的证书主体Subject字段是一致的,我们这里用证书KeyUsage进行区分)

服务端加密证书

Wireshark抓包详情(Certificate消息)

practical-crypto测试程序服务端使用的加密证书

从上面两张图可以看出:抓包显示证书的KeyUage - keyEncipherment字段,和服务端启动设置证书的X509v3 Key Usage -KeyEncipherment字段对应,都为加密证书。(实际上我们这里想要说明的是发送的加密证书无误,由于签名证书和加密证书的证书主体Subject字段是一致的,我们这里用证书KeyUsage进行区分)*

结论

GMTLS1.1作为中国密码技术的重要组成部分,在国内重要领域已广泛应用,也是密评评测指标中的关键卡点。本文结合TLS1.2协议流程以及GMTLS1.1协议demo程序和Wireshark抓包,对其进行了详细介绍。

目前主流计算机语言(JAVA、Python、NodeJs以及Golang等)官方都未支持GMTLS1.1,国密TLS协议包基本都是国内开发者基于主流语言的TLS程序报进行的二次开发,在实际应用和推广中仍然存在不少阻力,因此GMTLS1.1国际化任重道远。

顺便多一句:GMTLS1.1由于版本号的原因,够呛能够国际化。 TLS1.3支持国密算法倒是值得尝试(目前已有人提交了提案,有兴趣的可以参考 -> https://datatracker.ietf.org/doc/html/rfc8998

参考资料

TLS原理与实践(四)国密TLS的更多相关文章

  1. WebSocket原理与实践(四)--生成数据帧

    WebSocket原理与实践(四)--生成数据帧 从服务器发往客户端的数据也是同样的数据帧,但是从服务器发送到客户端的数据帧不需要掩码的.我们自己需要去生成数据帧,解析数据帧的时候我们需要分片. 消息 ...

  2. OpenSSL 1.1.1 国密算法支持

    OpenSSL 1.1.1 国密算法支持 https://www.openssl.org/ https://github.com/openssl/openssl OpenSSL 1.1.1 新特性: ...

  3. SSL/TLS 原理详解

    本文大部分整理自网络,相关文章请见文后参考. SSL/TLS作为一种互联网安全加密技术,原理较为复杂,枯燥而无味,我也是试图理解之后重新整理,尽量做到层次清晰.正文开始. 1. SSL/TLS概览 1 ...

  4. SSL/TLS原理详解

    本文大部分整理自网络,相关文章请见文后参考. 关于证书授权中心CA以及数字证书等概念,请移步 OpenSSL 与 SSL 数字证书概念贴 ,如果你想快速自建CA然后签发数字证书,请移步 基于OpenS ...

  5. [No0000126]SSL/TLS原理详解与WCF中的WS-Security

    SSL/TLS作为一种互联网安全加密技术 1. SSL/TLS概览 1.1 整体结构 SSL是一个介于HTTP协议与TCP之间的一个可选层,其位置大致如下: SSL:(Secure Socket La ...

  6. 2017-2018-2 20179204《网络攻防实践》第十三周学习总结 python实现国密算法

    国密商用算法是指国密SM系列算法,包括基于椭圆曲线的非对称公钥密码SM2算法.密码杂凑SM3算法.分组密码SM4算法,还有只以IP核形式提供的非公开算法流程的对称密码SM1算法等. 第1节 SM2非对 ...

  7. 开源项目SMSS发开指南(四)——SSL/TLS加密通信详解

    本文将详细介绍如何在Java端.C++端和NodeJs端实现基于SSL/TLS的加密通信,重点分析Java端利用SocketChannel和SSLEngine从握手到数据发送/接收的完整过程.本文也涵 ...

  8. kafka原理和实践(四)spring-kafka消费者源码

    系列目录 kafka原理和实践(一)原理:10分钟入门 kafka原理和实践(二)spring-kafka简单实践 kafka原理和实践(三)spring-kafka生产者源码 kafka原理和实践( ...

  9. 图解ARP协议(四)代理ARP原理与实践(“善意的欺骗”)

    一.代理ARP概述 我:当电脑要访问互联网上的服务器,目标MAC是什么? 很多小伙伴在刚学习网络协议的时候,经常这样直接回应:不就是服务器的MAC嘛! 这时我会反问:那电脑怎么拿到这个服务器的MAC地 ...

  10. Hyperledger Fabric国密改造

    Fabric国密改造是个什么概念?我们来思考以下4个问题: 为什么偏偏是密码算法?(WHY?) 什么是国密算法?(WHAT?) 改造切入点什么?(WHERE?) 如何实现国密支持?(HOW?) 1.为 ...

随机推荐

  1. 14.6 Socket 应用结构体传输

    当在套接字编程中传输结构体时,可以将结构体序列化为字符串(即把结构体的所有成员打包成一个字符串),然后将字符串通过套接字传输到对端,接收方可以将字符串解析为结构体,然后使用其中的成员数据.这种方法通常 ...

  2. spring框架中RESTFUL接口相关注解

    1.说明 springboot 是国内最常用的web框架,因为它的http server功能是最重要的.本文列举了一些现在通用的restful形式的接口所需要的注解 2.@RequestMapping ...

  3. 在K8S中,节点故障驱逐pod过程时间怎么定义?

    在Kubernetes中,节点故障驱逐Pod的过程涉及多个参数和组件的相互作用.以下是该过程的简要概述: 默认设置:在默认配置下,节点故障时,工作负载的调度周期约为6分钟. 关键参数: node-mo ...

  4. Hive-分区取TOP N问题

    问题背景 设想你对用户在不同品类上的行为打分聚合后得到这样一个表 user_cate_score uid cate score 1 1 0.3 2 2 0.5 8 3 0.9 现在,你想将每个品类的T ...

  5. 使用python进行视频图片提取

    操作系统 : Windows 10 [版本 10.0.19043.1165] Python 版本 : 3.9.2_x64 可以借助python代码使用opencv实现,命令行示例代码如下: # pyt ...

  6. html知识概念(不含标签)

    CS架构与BS架构 C/S架构 Client(客户端) / Server(服务器) 需要安装客户端使用,哔哩哔哩客户端.腾讯视频客户端等 需求安装.需要更新.不跨平台 B/S架构 Browser(浏览 ...

  7. jq 实现select 下拉框的联动效果

    实现联动的代码 $(document).ready(function() { $("#selectone").bind("change",function(){ ...

  8. 【Unity3D】地面网格特效

    1 前言 ​ 本文实现了地面网格特效,包含以下两种模式: 实时模式:网格线宽度和间距随相机的高度实时变化: 分段模式:将相机高度分段,网格线宽度和间距在每段中对应一个值. ​ 本文完整资源见→Unit ...

  9. 使用synchronized对并发性的影响

    1 前言 非静态方法的同步锁是当前对象(this)(对象锁) 静态方法的同步锁是当前类的字节码(类锁) 不同的锁之间能并发 2 同一对象内 本节主类与资源类如下: class Resorce{ //资 ...

  10. Vue+SpringBoot+ElementUI实战学生管理系统-2.搭建Vue+elementUI脚手架

    1.项目介绍 前一片介绍了项目的整体情况,这一篇开始搭建前端工程,需要的朋友可以拿去自己定制.:) 2.获取源码 源码是捐赠方式获取,详细请QQ联系我 :)! 3.项目截图 登录页 列表操作 动态图 ...