资讯详情

修改 protoc-gen-go 生成器实现 protobuf 字段名混淆的 3 处改动指南

📅 2026/11/6 1:21:11 | 华诺云谱 👁 阅读
修改 protoc-gen-go 生成器实现 protobuf 字段名混淆的 3 处改动指南
修改 protoc-gen-go 生成器实现 protobuf 字段名混淆的 3 处改动指南【免费下载链接】protobufGo support for Googles protocol buffers项目地址: https://gitcode.com/gh_mirrors/prot/protobufprotobuf 里的 .proto 文件经 protoc 编译成 Go 绑定文件 .pb.go 后结构体字段名、getter 名、枚举常量名全部明文躺在代码里internal/testprotos/proto3_proto/test.pb.go 中Name、HeightInCm这些字段就是现成例子。拿到二进制的人顺着字段编号对一遍 tag 就能还原传输内容的结构。本文的做法是对 protoc-gen-go/generator/generator.go 做protobuf 字段名混淆改造让生成器输出F1、F2这类无意义短标识符同时保证线上字节流一字节不变。一、方案全景只动标识符不动 tag一句话概括改的是标识符叫什么把字段和枚举常量的 Go 名字换成编号派生的短名不动的是线上写什么字段编号、wire 类型、name里的原始字段名全部由goTag统一生成源头是 descriptor 里的原名一行都不改这样序列化字节流天然不变新旧两份 .pb.go 可以互相解码。二、动手前环境与文件清单Go 工具链加 protoc。仓库内 internal/testprotos/regenerate.bash 锁定的版本是 protoc v3.9.1、protoc-gen-go v1.3.2建议保持一致。获取代码git clone https://gitcode.com/gh_mirrors/prot/protobuf需要改动的文件只有 protoc-gen-go/generator/generator.goprotoc-gen-go/main.go 是插件入口编译时用到但不需要动。风险一句话generator包已被官方标记 deprecatedgenerator.go 的init里每次构建都会打警告本文方法只适用于走这条旧生成链的项目且混淆后的产物基本没法肉眼调试只建议用于对外发布的构建。三、核心改动3 个改动点改动点 1字段标识符改用字段编号派生为什么改generateMessagegenerator.go 2179 行起里每个字段的 Go 名来自CamelCase(*field.Name)2222 行getter 名是Getbase。只要替换base结构体字段、getter、oneof 成员会一起变改一处就够。改动前base : CamelCase(*field.Name) ns : allocNames(base, Getbase)改动后base : F strconv.Itoa(int(field.GetNumber())) ns : allocNames(base, Getbase)allocNames2195 行的去重逻辑原样复用字段编号在消息内不会重复天然无冲突。改动点 2goTag 一个字符都不碰为什么不动线上兼容性全部锁在 tag 里。goTag1449 行起用field.GetNumber()填编号、用field.GetName()填namejson tag 也在 2227 行直接取自*field.Name。只要不碰这段编号和原始字段名就原样留在 tag 里兼容性自动成立。对照效果// 改动前 Name string protobuf:bytes,1,opt,namename,proto3 json:name,omitempty // 改动后标识符变成 F1tag 原样保留 F1 string protobuf:bytes,1,opt,namename,proto3 json:name,omitempty改动点 3枚举常量用 E数值替换为什么改generateEnum1341 行起里常量名来自 1365 行的name : ccPrefix *e.Name。改成name : E strconv.Itoa(int(e.GetNumber()))两个配套细节是自洽的_name/_value两张映射表1371-1387 行的键用的是*e.Name原始字符串字段 tag 里的enum部分1505-1517 行取自 proto 类型名两者都不经过 Go 常量名所以String()和枚举 JSON 解析行为不会坏。可选改动点 4白名单参数只混淆指定消息生成器通过CommandLineParameters448 行把命令行参数收进g.Parammap。可以在generateMessage开头按g.Param[obfuscate]逗号分隔的消息全名判断是否启用混淆即可从 protoc 侧透传protoc --go_outobfuscatepay.PaymentRequest:user :./out your.proto四、 怎么验证没破坏序列化编译插件go build -o protoc-gen-go ./protoc-gen-go重新生成仓库自带测试 proto命令取自 internal/testprotos/regenerate.bashprotoc -I$(pwd) --pluginprotoc-gen-go./protoc-gen-go \ --go_outpathssource_relative:. internal/testprotos/proto3_proto/test.proto新旧 .pb.go 逐条比对protobuf:...tagdiff 应只剩标识符和GetXxx方法名的差异。字节级验收最小用例proto/proto.go 的 Marshal/Unmarshal 即可测试风格参考 proto/proto_test.gofunc TestWireCompat(t *testing.T) { old, _ : proto.Marshal(oldMsg) // 用标准生成器编出的结构体序列化 var m proto3_proto.Message if err : proto.Unmarshal(old, m); err ! nil { t.Fatal(err) } b, err : proto.Marshal(m) // 混淆后的结构体再序列化 if !bytes.Equal(b, old) { t.Fatal(wire bytes changed) } }通过标准就两条tag 零差异新旧 Marshal 输出逐字节相等。五、容易踩的坑现象混淆后同包编译报E1 redeclared。原因枚举常量是包级命名空间多个枚举里同号值会撞名。规避编号里带上枚举类型序号或文件前缀。现象oneof、map 字段重新生成后行为异常。原因oneof 成员的tname2301 行和 map 的protobuf_key/protobuf_val2290 行都基于原字段名与类型名生成。规避只改goNametag 和类型名一概不碰。现象重新生成的 .pb.go 编译不过。原因文件头有const _ proto.ProtoPackageIsVersion3这类运行时版本断言protoc 或生成器版本与产物不匹配就会断。规避按 regenerate.bash 记录锁定同一版本组合。现象JSON 输出的 key 变了。原因手抖改到了goTag的 json 段。规避json tag 本就取自原始字段名保持不动。现象按文找行号对不上。原因新版链路里 protoc-gen-go/main.go32 行附近实际调用的是 google.golang.org/protobuf 的 internal_gengo 新插件本仓库的 generator 包只是旧链路留存。规避先确认自己的 main.go 走哪条链新链项目需对 internal_gengo 做同构改造。结尾这套改法把读代码猜字段的逆向成本抬高了一截但混淆不是加密tag 里的name和 descriptor 字节仍完整保留真要防抓取得靠传输层加密与字段级脱敏可参考 proto/discard.go 的思路。把它当作纵深防御的一层而不是唯一手段。涉及的关键文件与模块生成器核心protoc-gen-go/generator/generator.go插件入口protoc-gen-go/main.go生成的示例文件internal/testprotos/proto3_proto/test.pb.go重新生成脚本internal/testprotos/regenerate.bash编解码运行时proto/proto.go、proto/properties.go测试参考proto/proto_test.go【免费下载链接】protobufGo support for Googles protocol buffers项目地址: https://gitcode.com/gh_mirrors/prot/protobuf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑