ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

国密SSL抓包实战:从Wireshark到GMTLS握手分析全流程

国密SSL抓包实战:从Wireshark到GMTLS握手分析全流程 1. 国密SSL到底是什么GMTLS和普通TLS差在哪1.1 先弄明白这套协议的身世做国密SSL项目这些年最让我头疼的不是配置而是抓包分析。内部网关切到GMTLS以后某次新版客户端发布后台一堆握手失败告警日志只有一句“bad cipher suite”。我直接开Wireshark抓包一帧一帧翻ClientHello才找到是客户端默认走旧套件把国密套件压到了第二位。那次之后我总结出一整套完整的抓包分析流程今天手把手分享给你适合做国密网关、安全合规改造、SSL卸载验证的同行参考。国密SSLGMTLS不是凭空发明的新协议它本质上是标准TLS/SSL框架的“算法换芯”。协议流程还是Hello、Key Exchange、Certificate、Finished这一套但里面的密码原语从RSA/AES/SHA换成了SM2/SM4/SM3。这就带来一个很直接的结果只要你会看普通TLS握手抓国密包的框架知识大部分通用但算法字段、证书解析、套件识别却完全不通用。具体来说SM2承担非对称加密和数字签名SM4是128位分组对称算法SM3输出256位摘要。三者组合成国密套件比如常见的ECC-SM2-SM4-CBC-SM3、ECDHE-SM2-SM4-GCM-SM3等。在这些套件里SM2用于密钥协商和证书签名SM4用于业务数据加密SM3负责握手过程的消息摘要和伪随机函数。理解了这条链路后面看Wireshark解析就不晕。1.2 国密套件和传统套件的字段差异用一张表快速对照最直观环节传统TLS国密GMTLS公钥算法RSA / ECDSASM2签名摘要SHA-256/SHA-384SM3对称加密AES-GCM / CHACHA20SM4-CBC / SM4-GCM密钥交换ECDHE / RSASM2密钥交换 / ECDHE-SM2证书签名算法sha256WithRSAEncryption等SM2withSM3标准依据RFC 5246/8446GM/T 0024、GB/T 38636在Wireshark里TLS封装层仍然叫TLS你不会看到协议名变成“GMTLS”。正确识别方式是通过Cipher Suite的值。常见的国密套件十六进制值如0xE011、0xE013不同标准版本和厂商实现可能有差异所以抓包时不要只记名字要同时记住套件值这对定位问题很重要。1.3 什么项目需要做GMTLS抓包结合我接触过的实际项目需要抓GMTLS包的场景大致分四类第一类是合规验收要出具抓包证据证明握手过程确实走了国密套件第二类是网关或负载均衡器升级后出现握手失败需要判断是算法套件不匹配、证书链不完整还是协议版本问题第三类是大量客户端兼容性测试要模拟不同系统版本、不同浏览器内核下的ClientHello差异第四类是性能问题通过抓包数握手的往返次数看是否因为缺省证书链导致额外的连接建立。还有一类容易被忽略运维同学在处理“能访问但页面很卡”时抓包发现每次请求都重新握手多半是服务端没开会话复用或者客户端的Session ID被网关重置。这种问题不抓包根本看不出来。2. 抓包前的环境准备别在第一步就翻车2.1 Wireshark安装与运行环境Windows上推荐下载官方最新稳定版安装过程中会提示安装Npcap建议勾选。Npcap是底层抓包驱动没它Wireshark连不上网卡。如果机器上以前装过WinPcap最好先卸载干净两个驱动共存的坑特别多。装完后如果还是“No interfaces found”多半是服务被禁用了用管理员身份打开services.msc把Npcap相关服务设为自动并启动。另外在远程桌面或虚拟网卡环境下使用Wireshark蓝屏概率会高一些尤其是Npcap版本较老时。普通有线网卡抓包基本没问题但涉及虚拟接口或拨号适配器时建议升级到最新Npcap版本或者干脆在目标服务器上用tshark命令行抓包避免图形界面带来的额外性能开销。2.2 让Wireshark正确识别国密套件这也是新手最容易懵的地方一帧一帧翻下去发现Wireshark的Cipher Suites列表里国密套件显示为Unknown (0xe011)顿时怀疑自己抓错包。其实Wireshark的TLS解析依赖IANA注册表而国密套件并没有在IANA里统一注册所以新版本即使能解码TLS层也无法把0xE011自动翻译成“SM2-SM4-CBC-SM3”这样的名字。我的建议是不要指望Wireshark自动显示国密套件名而是直接用显示过滤器匹配数值。常用的过滤器有tls.handshake.ciphersuite 0xe011 tls.handshake.ciphersuite 0xe013如果一次想列出所有国密套件可以用tls.handshake.ciphersuite 0xe011 || tls.handshake.ciphersuite 0xe013想更稳妥一点抓取完整ClientHello右键选中Cipher Suites字段能看到Wireshark解析出来的名称和值。把目标套件的值记下来后续所有按值匹配的过滤都围绕它做。2.3 抓包过滤器的两个阶段过滤条件要分开设置抓包前用BPF语法降低性能损耗抓包后用显示过滤缩小分析范围。比如知道网关IP是10.0.0.8、端口443抓包前就写host 10.0.0.8 and tcp port 443抓包结束后分析握手包时再叠加显示过滤器只看Handshake消息tls.handshake.type 1 || tls.handshake.type 2这样能快速定位到ClientHello和ServerHello避免在一堆Application Data里翻来翻去。如果关心证书链单独过滤证书消息tls.handshake.type 11注意TLS握手消息类型里1是ClientHello2是ServerHello11是Certificate12是ServerKeyExchange13是CertificateRequest15是ClientKeyExchange16是CertificateVerify20是Finished。这些数字在国密TLS里同样适用因为GMTLS沿用了TLS的消息结构。2.4 客户端到底要不要做额外配置普通Chrome和Firefox默认不支持国密套件如果直接访问国密HTTPS网关抓包时ClientHello里根本看不到0xE011之类的套件自然握不上手。所以测试前需要确认客户端具备国密能力要么是安全浏览器要么是装了国密SDK的测试程序要么是经过定制支持国密套件的OpenSSL。至于证书问题客户端如果没有导入国密根证书抓包时会看到服务端发来证书后客户端直接发送Alert报文。这种告警一般是bad_certificate或certificate_unknown。你以为问题在网络实际是客户端不信任根证书。建议抓包前先把根CA导入到系统证书库或浏览器信任区排除证书信任因素让每一层问题都独立暴露。2.5 抓包采集点怎么选抓包位置决定了你能看到什么。最推荐的是在客户端本机抓包能看到ClientHello和对方下发的完整证书链问题定位最快。如果客户端是手机或者嵌入式设备就需要在服务端侧或交换机镜像口抓。镜像口抓包要注意方向很多交换机默认只镜像入方向会导致只看到半边流量配置时建议“双向镜像”否则后续分析容易误判为“对方没回包”。有些场景需要在网关上同时抓“内网侧”和“外网侧”两个方向的包对比两边看到的Cipher Suite和证书顺序。我在做国密网关验证时经常这样操作一眼就能看出是客户端问题、服务端问题还是中间设备改写导致的问题。3. GMTLS握手协议字段拆解一帧一帧看懂3.1 ClientHello里的国密“三件套”打开抓包文件找到第一个握手包ClientHello。重点关注三个字段。第一个是Cipher Suites看里面是否包含国密套件值。如果列表里出现0xE011、0xE013说明客户端确实启用了国密如果全是传统套件问题就在客户端配置。第二个是Supported Groups传统TLS常见的是x25519、secp256r1国密客户端通常携带SM2曲线对应的扩展标识很多Wireshark版本把它显示为Unknown Group这不代表有问题。第三个是Signature Algorithms国密客户端一般会携带SM2-SM3组合对应OID为1.2.156.10197.1.501。以上三点可以总结成一张速查表字段传统值示例国密值示例说明Cipher Suites0xC02F (AES128-GCM)0xE011 / 0xE013需要按实际抓包确认Supported Groupsx25519 / secp256r1SM2曲线扩展Wireshark可能显示UnknownSignature Algorithmsrsa_pss_rsae_sha256sm2_sm3 (OID .501)可能显示为TLS 1.3格式这个阶段最容易踩的坑是客户端携带有国密套件但排位靠后服务器如果关闭了“国密优先”策略可能最终协商成传统套件。所以光看ClientHello不够必须继续看ServerHello。3.2 ServerHello决定最终“用哪把刀”ServerHello里的Cipher Suite是服务端最终选择的套件这是判断国密是否真正生效的关键字段。如果这里显示0xE013或客户端可识别的国密名称说明协商成功。如果显示的是AES-GCM之类的传统套件说明客户端虽然支持国密但服务端策略或证书类型导致回退到了普通TLS。还有一个细节国密SSL里服务端是否开启双向认证会影响后续流程。单向认证时服务端只需要下发证书链双向认证时ServerHello之后会有CertificateRequest消息然后客户端也要发证书和CertificateVerify。双向认证的抓包更容易出问题尤其是证书链不完整时证书验签会失败整个握手会在Finished之前中断。接着是Certificate消息服务端把证书链一次性下发。Wireshark在Certificate消息里按顺序列出证书通常是叶子证书在前中间证书在后根证书不一定下发。此时可以展开每个证书看签名算法是否为SM2withSM3。如果服务端下发的是RSA证书即使客户端套件里写着国密实际握手也会失败或回退这就是“证书算法与套件不匹配”的经典问题。3.3 密钥交换阶段SM2如何参与协商在TLS 1.2框架下国密SSL的密钥交换流程和ECDHE很像。服务端发送ServerKeyExchange里面携带临时公钥和签名客户端验证签名后发送ClientKeyExchange携带自己的临时公钥或加密后的预主密钥。只是这里的签名和加密都换成了SM2。如果服务端使用固定的SM2证书公钥做密钥交换ServerKeyExchange内容会简单一些如果是ECDHE-SM2模式则会有临时密钥对参与。抓包时看ServerKeyExchange时注意Wireshark是否识别出SM2参数。多数情况下它会显示一串二进制解析不出“SM2”字样这很常见。我的习惯是同时抓客户端日志两边对照确认密钥交换是否成功。这里有个实用技巧如果拿到的抓包里只有ClientHello、ServerHello但没看到ServerKeyExchange和Finished一般不是抓包不全而是握手在证书验证阶段就中断了。优先去查告警报文Alert它会告诉你具体失败原因。3.4 握手完成后如何判断流量是“真加密”国密握手完成后所有业务数据都封装在Application Data里Wireshark默认不解密。此时如果你拿到会话密钥文件可以在Wireshark的TLS偏好设置里指定(Pre)-Master-Secret log filename再用SSLKEYLOGFILE方式导出密钥理论上可以看到明文HTTP层。国密场景里部分自研协议栈可能不输出标准格式的key log解密不了就很正常不要因此怀疑抓包方法不对。在没有密钥的情况下可以通过几个侧面特征判断是否真走国密国密套件下SM4-CBC加密密文长度一般是16字节的整数倍如果走SM4-GCM则每个记录末尾会带16字节的认证标签。另外国密TLS版本多为TLS1.2报文头部可能不出现TLS1.3特有的ChangeCipherSpec省略行为。这些特征能帮你快速排除“只是改了证书但没改加密算法”的假国密。3.5 别忽略TLS Alert报文抓国密握手时Alert消息是最快定位问题的入口。常见告警值整理成表Alert值含义常见场景20bad_record_mac密钥协商失败或数据被篡改40handshake_failure没有共同支持的套件或参数42bad_certificate证书格式错误或验签失败43unsupported_certificate客户端不支持服务端证书类型46certificate_unknown证书信任路径无法建立48unknown_ca客户端不信任服务端根CA70protocol_versionTLS版本不兼容看到Alert时先看它出现在哪个握手环节。出现在ServerHello之后基本是证书或密钥交换问题出现在Finished之后通常是客户端验证服务端发来的Finished消息失败这时候要重点看Key Exchange参数是否匹配。4. 证书链验证从Wireshark到命令行一步都别少4.1 在Wireshark里直接看证书链的完整度常用做法是点击握手包里的Certificate消息逐层展开证书。Wireshark通常能解析X.509证书的Issuer、Subject、有效期、签名算法等字段。你需要核对三个信息叶子证书的Issuer是否等于中间证书的Subject中间证书的Issuer是否等于根证书的Subject以及整条链里的签名算法是否都是SM2体系。如果服务端只发了叶子证书没有下发中间证书Wireshark里看到的就是孤零零一个证书客户端在本地找不到可信任路径就会报证书链不完整。这是国密网关部署里最常见的问题之一。Wireshark抓包能非常直观地展示服务端到底发了几个证书比看配置猜测要快得多。导出证书通常用这种方式在Certificate字段上右键选择Export Packet Bytes把证书原始DER文件保存下来。实际操作中我更推荐这个方法因为文件格式可控方便接下来命令行验证。4.2 用命令行走一遍证书链验证拿到证书文件后用命令行验证。如果机器上装了GmSSL最直接gmssl verify -CAfile ca.pem -untrusted intermediate.pem server.pem其中ca.pem是根证书intermediate.pem是中间证书server.pem是服务端证书。如果验证通过会提示OK如果失败会告诉你是在哪一层断的。用OpenSSL验证SM2证书时部分版本对SM2的OID支持不全可能出现unsupported signature algorithm这不是证书本身坏了是工具不认识SM2换GmSSL或者新版OpenSSL即可。另一个常用命令是检查服务端实际下发的证书链openssl s_client -connect 10.0.0.8:443 -servername example.com -showcerts这个命令能直接看到握手中的证书链包括服务端有没有把中间证书拼进去。对于国密协议栈如果不支持标准s_client连接可以用GmSSL对应的客户端命令具体参数看版本。命令行的好处是能看到证书链的发送顺序这与Wireshark抓包结果互相印证基本就能定位时序问题。4.3 证书链验证失败速查表把实战中遇到最多的报错整理成表方便你直接对号入座常见报错直接原因排查方向unable to get local issuer certificate本机没有该CA根证书导入根CA或指定-CAfilecertificate chain incomplete服务端未下发中间证书在Web服务器配置证书链文件self-signed certificate服务端证书为自签确认验证方式是否允许自签unsupported signature algorithm工具不认识SM2签名换GmSSL或升级OpenSSLsignature verification failure证书签名与签发者不对应重新申请或确认证书内容未篡改certificate is not allowed to sign中间证书缺少CA基本约束检查证书扩展是否含Certificate Sign这里我想特别提醒国密证书链的中间证书很多是双证书体系签名证书加密证书。有的网关要求签名证书和加密证书分别配置有的则只需要签名证书。抓包时如果发现证书链有两套别慌先确认服务端配置的是哪一套再匹配客户端的信任库。两套证书混用是国密项目里翻车率极高的点。4.4 服务端证书链配置的实操经验以Web服务器为例配置国密HTTPS一般需要三个文件ca.crt、server.crt、server.key。关键是server.crt必须把中间证书一起拼接成链文件顺序是“叶子证书在前中间证书在后”不能反过来否则服务端下发的证书顺序会让客户端解析异常。拼接命令很简单cat server.crt intermediate.crt fullchain.crt配置完成后不要急着谢天谢地用s_client或GmSSL自己连一次确认下发的证书数量是两个而不是一个。这个动作只要10秒能省下后面成堆的工单。另外证书到期前一定要把监控做起来尤其是国密证书的签发周期往往比传统证书更复杂到期前30天换证别等客户端告警一片再救火。4.5 检查证书有效期与KeyUsage证书链完整不代表证书可用。有次客户反馈“国密浏览器访问网关报证书错误”抓包一看证书链完整、签名算法也对最后发现是证书KeyUsage里没有Digital Signature这一项导致服务端无法用私钥做签名。KeyUsage这个字段藏在证书扩展里Wireshark能解析但很多人不会主动看。国密证书的KeyUsage通常需要支持Digital Signature和Key Encipherment部分场景还需要Key Agreement。验证时可以用以下命令查看证书扩展确认后再上生产gmssl x509 -in server.pem -text -noout | grep -A1 Key Usage另外有效期问题在国密场景里也容易出现加密证书和签名证书的有效期可能不同一个过期一个没过期导致握手时服务端选错证书。抓包时顺手看一眼证书的有效期能少踩很多坑。5. 常见抓包问题与排查技巧老手也踩过的坑5.1 明明在抓包却看不到任何TLS报文这种情况出现频率很高。先看硬件层面如果在Windows上选了WLAN接口而无线网卡本身有包接收限制需要把Wireshark的接口设置为允许混杂模式否则只能看到自己本机的流量看不到其他设备的包。如果是服务器尽量在镜像口抓包而且要注意交换机的端口镜像是否有方向限制某些低端交换机只镜像入方向或只镜像出方向导致只看到一半报文。另一个常见坑是TLS会话复用。客户端第一次握手成功后后续请求会走Session Ticket或Session ID复用不再进行完整握手。你以为抓不到流量实际上流量早就加密了只是在恢复会话。解决办法是清除浏览器缓存并重启浏览器或者在服务器端临时禁用会话复用强制每次都做完整握手。5.2 看到了TLS但不知道是不是国密如前面所说国密包在Wireshark里显示的协议名仍是TLS不会自动变成GMTLS。判断依据只能是Cipher Suite值和证书签名算法。建议把常用国密套件值抄在本子上分析时直接用tls.handshake.ciphersuite 0xe013这类过滤快速定位。如果发现ServerHello选择的套件不是国密说明中间设备做了回退问题大概率在服务端而不是抓包方法。这个现象尤其容易误导验收团队写验收报告时截图里全是TLS字样看不出国密特征。正确做法是截两手一手是Cipher Suites列表里的国密值一手是证书的SM2签名OID。两张图合在一起才算完整证据链。5.3 想解密HTTPS流量但始终解不开首先明确解密SSL的前提是拿到密钥材料。常用的三种方式一是在客户端设置SSLKEYLOGFILE环境变量让浏览器导出会话密钥二是在服务端打开调试日志输出预主密钥三是在网关设备上开启密钥导出功能。拿到密钥文件后在Wireshark的Preferences、Protocols、TLS里配置key log路径然后重新载入抓包文件才能看到解密后的HTTP明文。但在国密环境里要降低预期很多国密协议栈并不走标准OpenSSL的key log格式导出的可能是厂商自定义的二进制密钥文件Wireshark不一定能直接解密。这时候我的建议是抓包分析和业务日志双管齐下用抓包确认握手、套件、证书链是否正确业务数据是否加密成功交给服务器日志和业务系统去验证。5.4 长时间抓包导致卡顿或文件过大遇到需要连续抓几小时甚至几天的场景用Wireshark GUI里的抓包选项设置文件大小上限和轮转即可比如每个文件100MB、每写满一个文件自动新建。命令行tshark也可以做到tshark -i eth0 -f tcp port 443 -b filesize:102400 -b files:20 -w gmtls_capture.pcapng这样最多写20个100MB的文件对磁盘压力和后续分析都比较友好。如果抓包时间极长建议用单独的抓包服务器把流量镜像过来再抓避免在生产实例上边跑业务边抓包既影响性能又容易误伤数据。5.5 Wireshark解析不出厂商扩展怎么办国密SSL没有完全统一的国际标准很多厂商会加私有扩展比如在ClientHello里携带厂商ID、算法组标识、证书类型等。Wireshark看不懂这些扩展很正常显示为Unknown Extension。遇到这种情况不要纠结扩展名先看整体流程是否正常再结合厂商日志确认扩展含义。如果厂商支持Wireshark插件或协议解析器装上可以显著减少人工判断时间。我个人的经验是只要ClientHello、ServerHello、证书、密钥交换、Finished这五个环节在协议格式上没问题个别私有不认识字段不影响整体判断。别让一个未知扩展带偏了整个排查方向。5.6 国密浏览器、普通浏览器、OpenSSL三方兼容怎么办在做兼容性测试时经常遇到同一台服务器国密浏览器能访问、普通浏览器却报错或者反过来。抓包对比ClientHello就能看出来国密浏览器只带国密套件普通浏览器只带传统套件服务端必须根据客户端选择对应证书和算法。如果服务端没有做“国密/传统自适应”就会导致其中一方握手失败。解决办法通常是在网关或负载均衡器上开启“双证书自适应”模式根据ClientHello自动选择国密证书链或传统证书链。抓包时要分别从两种客户端各抓一次对比ServerHello里选择的套件和下发的证书类型确认切换逻辑正确。这类问题在纯软件层面看不出名堂抓包一对比原因立刻浮出水面。6. 写在最后我的一点实操体会这套抓包分析法我用了很多次从最开始对着0xE011发懵到现在几分钟能定位问题核心就一句话把国密SSL当作普通TLS协议的“算法替换版”来看协议流程靠Wireshark算法细节靠证书和套件值。如果这篇能帮你少走一点弯路那就值了。遇到国密握手、证书链验证的问题欢迎在评论里抛出来一起交流我基本上每天都会过来看看。
返回列表