协议安全
概述
协议层是攻击者的第一道突破口:抓包分析、篡改消息、重放请求。协议安全的核心三件事:加密(防窃听,AES/RSA 混合)、完整性校验(防篡改,HMAC)、防重放(Timestamp + Nonce)。本文设计完整的协议安全方案。
一、消息加密
1.1 加密方案选型
加密算法:
对称加密(AES):快,适合大量数据
非对称加密(RSA):慢,适合少量关键数据
混合加密(推荐):RSA 交换密钥 + AES 加密消息
密钥管理:
服务端持有 RSA 私钥(客户端持有公钥)
会话密钥(AES Key)动态生成
定期更换会话密钥混合加密流程:
1. 握手:客户端生成随机 AES Key
2. 用服务端 RSA 公钥加密 AES Key 发送
3. 服务端用私钥解密得到 AES Key
4. 后续消息用 AES Key 加解密(对称,快)
优势:
RSA 只加密密钥(少量数据)
AES 加密消息体(大量数据,效率高)// AES 加密消息体示例
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, sessionKey, iv);
byte[] encrypted = cipher.doFinal(payload);1.2 加密范围
加密范围选择:
全量加密:安全最高,性能开销
敏感字段加密:性价比
关键消息加密:平衡
游戏实践:
登录/充值/交易 → 加密(关键)
对局高频消息 → 可只做签名(性能)
按消息类型配置加密策略注意:
加密不等于安全(密钥管理是关键)
客户端密钥可被逆向 → 以服务端安全为前提
性能开销评估(压测验证)二、消息完整性校验(HMAC)
2.1 HMAC 原理
HMAC(哈希消息认证码):
用密钥 + 消息计算摘要
防篡改(内容改变摘要不一致)
用途:
消息完整性校验
防中间人篡改
// HMAC-SHA256 示例
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(secretKey);
byte[] digest = mac.doFinal(payload);2.2 签名设计
消息签名:
服务端与客户端共享密钥(或协商)
消息体 + 共享密钥 → HMAC 摘要
接收方重算比对(不一致 → 拒绝)
防伪造:
密钥不随消息发送(只用于计算)
服务端密钥不下发(RSA 保护的会话密钥)
防重放结合(见下节)// 协议头增加签名字段
Header: magic(2) + version(1) + flags(1) + opcode(2)
+ length(4) + seq(4) + timestamp(4) + nonce(4)
+ hmac(16) # 对 header + body 计算签名 vs 加密:
加密防"窃听"(看不懂)
签名防"篡改"(改不了)
两者独立(可只签名不加密)三、防重放攻击
3.1 重放问题
重放攻击:
抓包记录合法请求 → 重复发送
例:重复购买、重复领取、重复战斗操作
危害:
重复扣款/重复发货
刷操作次数
防护思路:
让旧消息失效(时间窗)
让同消息只生效一次(Nonce 去重)3.2 Timestamp + Nonce
方案:时间戳 + 随机数
1. 消息带 timestamp(发送时间)
2. 服务端校验 |now - timestamp| < 窗口(如 60s)
3. 消息带 nonce(随机数)
4. 服务端记录已用 nonce(窗口期内)
5. 重复的 nonce 拒绝
// 防重放校验
if (Math.abs(now - msg.timestamp) > WINDOW) {
return reject("过期消息");
}
if (!nonceStore.tryAdd(msg.nonce, WINDOW)) {
return reject("重复消息");
}Nonce 存储:
Redis Set(窗口期内去重)
定期清理过期 nonce
内存 + 分布式(多节点共享用 Redis)
注意:
时间窗要容忍时钟偏差(客户端时钟)
窗口过大 → 重放风险;过小 → 误拒// Redis 去重(原子)
Boolean first = redis.setIfAbsent("nonce:" + nonce, "1",
Duration.ofSeconds(WINDOW));
if (!first) {
return reject(REPLAY); // 已见过此 nonce
}四、防协议篡改设计
4.1 综合防护
协议安全组合:
加密:防窃听(关键消息)
HMAC:防篡改(全部消息)
Timestamp + Nonce:防重放
服务端权威:防逻辑利用(见下节)
综合校验流程:
1. 解密(关键消息)
2. 验 HMAC(完整性)
3. 验时间戳(时效)
4. 验 nonce(去重)
5. 业务校验(服务端权威)4.2 协议演进与版本
协议版本:
协议头带 version
版本不兼容 → 客户端升级
灰度切换(新协议逐步启用)
安全升级:
发现漏洞 → 更新协议/密钥
紧急下线异常版本
密钥轮换(定期更换)常见坑:
密钥硬编码在客户端 → 易被逆向提取
只加密不签名 → 可篡改(密文重放)
时间窗过宽 → 重放风险
nonce 不清理 → 内存膨胀五、实现要点
协议安全清单:
混合加密(RSA 换密钥 + AES 加密)
HMAC 完整性校验(全部消息)
Timestamp + Nonce 防重放(Redis 去重)
协议版本管理
密钥轮换
工程注意:
加密/签名在编解码层(透明处理)
性能开销压测验证
安全配置与密钥集中管理
异常(验签失败)记录日志
常见坑:
密钥泄露 → 轮换 + 安全存储
验签失败静默 → 告警
只防护部分消息 → 全部覆盖
过度加密 → 性能下降与其他系统衔接:
编解码层 → 自定义协议章节
服务端权威 → 服务端权威章节
网关防护 → 网关章节
审计 → 日志审计章节