摘要

加密流量分类需要从内容不可见、样本不均衡的流量数据中,提取区分度强、鲁棒性好的流量表征,以实现精准分类;这对网络安全与网络管理至关重要,但也极具挑战。现有方法过度依赖人工设计的深层特征,严重依赖数据规模,难以泛化到未知流量场景。如何利用开放域海量无标注流量数据学习强泛化表征,仍是关键难题。

本文提出ET‑BERT(加密流量 Transformer 双向编码器),从大规模无标注加密流量中预训练数据报级上下文感知表征。预训练完成后,仅需少量任务专属标注数据微调,即可在五大加密流量分类任务上达到当前最优性能:

  • ISCX‑VPN‑Service 数据集 F1:98.9%(↑5.2%)
  • 安卓跨平台任务 F1:92.5%(↑5.4%)
  • CSTNET‑TLS 1.3 任务 F1:97.4%(↑10.0%)

同时,本文通过加密算法随机性分析,从理论上解释了预训练模型的优异表现,为理解加密流量分类能力的边界提供了重要依据。代码开源:https://github.com/linwhitehat/ET-BERT

关键词:加密流量分类、预训练、Transformer、掩码突发模型、同源突发预测

概述

传统方法:

  1. 提取残留的明文特征。
  2. 提取流量的统计特征,并结合传统机器学习算法处理无明文的加密流量。
  3. 提取原始流量特征,然后用 CNN、RNN 等神经网络去学。

效果:

  1. 这类方法不适用于 TLS 1.3 等新型加密技术,因为其明文信息变得更少、更难获取。
  2. 这类方法难度大,高度依赖人工设计特征,泛化能力有限。
  3. 性能显著提升,但这类方法极度依赖标注数据的数量与分布,容易导致模型偏置,且难以适配新型加密流量。

在 2018 年之后,AI 领域的“三巨头”(BERT、GPT、Transformer)大获成功,“预训练 + 微调”就成了自然语言处理(NLP)和计算机视觉(CV)的标准套路。

但在“加密流量分类”领域,主流做法其实还是上面的传统方法。

为什么以前不用?
因为流量数据不像人类语言/文本/图片那样有天然的语义,以前的研究者觉得“流量太杂了,没法学出通用的预训练模型”。

最新研究有尝试直接套用预训练技术,在 VPN 流量分类上取得一定提升。不过,缺乏面向流量专属的预训练任务和合理的输入表示,无法充分发挥预训练模型的优势

该论文提出一种面向加密流量分类的新型预训练模型:

  • ET-BERT,直接用原始流量,无监督预训练,然后监督微调。
  • 首先提出一种原始流量表示方法,将数据报转换为类似语言的 “词元”token,供预训练使用。每条流量流采用一种传输导向结构(BURST)表示,作为模型输入。
  • 预训练阶段采用 Transformer 结构,在海量无标注加密流量上通过自监督学习,学到数据报级的通用流量表征。还设计两项专属预训练任务。

数据预处理+预训练+微调

![[Pasted image 20260519192959.png|697]]
ET‑BERT 的数据处理分两大块:

  1. 预训练(无标签,生成的 BURST 文本)
  2. 微调(有标签,生成的 JSON 数据集)

数据处理

拿到需要训练的数据集(是个大的pcap),输入pcap_path、word_dir、word_name、output_split_path、pcap_output_path,然后终端运行python dataset_generation.py,最后产出burst文本 。
中间会调用函数convert_pcapng_2_pcap()转换 pcapng → pcap、split_cap()切分 Session、get_burst_feature()生成 BURST 文本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# data_process/dataset_generation.py
# 调用函数
split_cap(
pcap_path, # pcap 所在的根目录
pcap_file, # 具体 pcap 文件的完整路径
pcap_name, # 这个 pcap 的名字
pcap_label='', # 类别标签
dataset_level='flow' # flow(默认) 或 packet
)

# flow:按Session(五元组)分
# packet:按包分,数据粒度更小

# 返回的是数据切分后的路径

2.generation()
读取切好的小 PCAP,过滤太小、损坏、无效的文件,随机抽取每类流量样本,提取 payload,保存成 dataset.json 数据集,输出 X(特征)、Y(标签)给模型训练。

转 Token(BURST2Token)
原文:
![[Pasted image 20260521144522.png]]

scapy 读取 pcap文件,提取原始字节然后转成16进制字符串。利用 “相邻字节之间有相关性” 调用函数bigram_generation()将每两个连续十六进制字符两两一组
get_burst_feature():核心函数。读取 Flow,提取 Payload,按方向切分 BURST。
get_feature_flow():Flow 级别的特征提取。
get_feature_packet():Packet 级别的特征提取。

预训练

把上一步得到的所有 Token,转换成模型能处理的向量。这个向量又是由词元嵌入 + 位置嵌入 + 分段嵌入三步处理得到的,然后把这个向量输入模型开始预训练任务。
![[Pasted image 20260521144320.png]]

词元嵌入:

  • [CLS]:句子开头(最后用来分类)
  • [SEP]:分开两段 BURST
  • [PAD]:长度不够时补空位
  • [MASK]:预训练时遮住一部分

开始两项预训练任务:
1.掩码突发模型(Masked BURST Model)
该任务与 BERT 所采用的掩码语言模型类似。核心区别在于:ET‑BERT 所处理的流量词不具备明显语义,模型旨在捕捉数据报字节间的依赖关系。

在预训练过程中,输入序列中的每个词都有 15% 的概率被随机掩码

  • 80% 概率替换为 [MASK]
  • 10% 概率替换为随机词
  • 10% 概率保持不变

2.同源突发预测(Same-origin BURST Prediction)
本任务通过同源突发预测(SBP),学习 BURST 内部数据包之间的依赖关系。具体而言,采用二分类器判断两个子 BURST 是否源自同一个原始 BURST。在构造子 BURST 对(sub-BURSTA、sub-BURSTB)时:

  • 50% 概率,sub-BURSTB 是 sub-BURSTA 的真实后续段;
  • 50% 概率,sub-BURSTB 是随机取自其他 BURST 的片段。

把流量切成两半,一半真配对、一半乱拼,让模型判断是不是一伙;逼模型学流量的前后顺序和整体结构。

最后输出:768 维特征向量 = 一串固定长度(768 个)的小数,每个 token 对应一串。

微调

微调时只拿 [CLS] 那一串 768 维向量,再配上JSON 里的标签(如微信、VPN),教模型:这串数字 = 对应标签

python main.py

main

dataset_extract()

dataset_generation.generation()

split_cap() ❌(splitcap=False)

get_feature_packet() ✅

统计每类样本数

8:1:1 切分

保存 .npy(带标签,给微调)

models_deal()

生成带标签 TSV(给预训练脚本读)

产出nolabel_test_dataset.tsv

  • 数据预处理:Datagram2Token(数据报转令牌)
    从 PCAP 流量文件中,先按会话流切分、再重组为连续的 突发流量(BURST)片段,接着把十六进制数据报通过二元组令牌化(Bigram Tokenization)转换成模型可处理的令牌单元,并拆分为子突发流量对,完成流量数据的结构化改造,为预训练做好准备。

  • 模型预训练:学习流量通用表征
    令牌化后的流量数据,会被加上令牌嵌入、位置嵌入和分段嵌入,输入 ET-BERT 模型。模型通过两个自监督任务学习流量规律:突发流量掩码模型(Masked BURST Model) 通过预测被掩码的令牌学习流量上下文关系,同源突发流量预测(Same-origin BURST Prediction)** 学习不同子突发流量的来源关联性,最终得到能捕捉流量行为特征的通用表征。

  • 下游微调:适配具体分类任务
    预训练完成后,根据不同场景(如应用分类、VPN 流量识别、Tor 流量检测)进行微调:将带标签的流量数据输入模型,利用预训练好的 ET-BERT 提取的流量表征,在对应分类任务上训练,让模型适配特定业务场景,实现精准的加密流量分类。