8.3 城墙与户籍:安全与隐私


8.3 城墙与户籍:安全与隐私

摘要:沙盘验收合格,小镇要开进真实世界了——真实世界的邮局外有骗子,户籍处里有想偷名单的家贼。本节给小镇砌墙装门:先画威胁画像(冒名、篡改、重放、泄密、淹没),再砌认证的城墙(含消息认证码的火漆印章与防重放的一次性编号),最后给户籍处立新规矩——差分隐私,让报表能看、单户泄不出。全部防线用可运行代码演练。

前八节的机制——合同网、拍卖、声誉、联合意图——都默认一条君子协定:镇民说自己是自己,信件不被半路拆改,报表只报总数。沙盘里这条协定白送;一进真实网络,它就是第一个被打穿的假设。安全的特殊性在多智能体系统里比在单机软件里更扎眼:系统没有边界,别的智能体就是你的运行环境;没有全局警察,执法者自己也是智能体;攻击者往往持着合法户口,是"内部人"。所以这一节不是给单机程序上锁,而是给一座开放小镇设计治安制度——它和第 3 章的组织规范、第 5 章的信任声誉本是同源:都是改变对方的收益结构,而不是加一把更粗的铁锁。

威胁画像:门外的骗子和墙内的家贼

把小镇日常里能出的安全事故排成一排,每类都配一段镇内剧情:

冒名入市。骗子伪造户籍混进镇门,以正规镇民身份参与招标,中标后交付一堆废料,或者干脆在关键表决里投出破坏票。对应技术名词是身份伪造与女巫攻击(第 5 章声誉系统领教过它的口碑版本,这里是户口本版本)。

半路改信。邮差(路由节点或被攻陷的智能体)拆开投标信,把"五百枚金币"改成"五千枚"再封上——收信方毫无察觉。窃听、篡改、伪造是同一件事的三个面:通信信道不可信。

旧信重投。攻击者不拆信也不改信,只把去年的一份有效投标书原样再投一遍——如果协议不看日期,一封过期授权信就能再骗一次门房。重放攻击专治"只验印章不验新鲜"的粗心协议。

报表泄密。户籍处如实公布"全镇领补助的户数与分布",看着谁也没得罪;但攻击者手里握着其余各户的信息,拿公布数一减,孤零零那户领没领补助立刻现形。差分攻击不需要黑进数据库,只靠公开数字做减法。

骚扰淹局。海量垃圾消息涌向邮局,正常信件反而挤不进去——拒绝服务未必攻破城墙,只需让城门堵死。在多智能体系统里它还有个温柔版本:某个智能体疯狂广播询价,把别的镇民的计算资源全耗在回复上,自己坐收清净。

威胁 镇内剧情 首选防线 防线失效条件
冒名入市 骗子持假户籍参与招标投标 户籍科签发身份证书,进门先验 根证书或私钥失窃
半路改信 邮差拆标书改价格再封上 加密信道加消息认证码 密钥复用、弱算法
旧信重投 过期授权书被原样再投一遍 编号加时间戳,验新鲜性 校验端懒得查序号
报表泄密 公开统计被差分出单户底细 差分隐私加噪发布 隐私预算被反复查询耗干
骚扰淹局 垃圾询价挤占邮局与算力 配额限流加信誉门槛 攻击者换马甲重置信誉

砌墙工程:认证、授权与新鲜性

三件套按顺序砌。认证回答"你是谁":镇门口的户籍科(证书签发机构)给每位镇民发一本难以伪造的户口簿(公私钥对),见面先互验户口再谈事。授权回答"你能动什么":能力令牌机制——资源方发给智能体一张写明"可动用车库三号、限用至周五"的票据,票据本身带防伪戳,转借无效。这其实是把第 3 章电子机构里的"角色权限"做成了可验证的物理凭证。新鲜性回答"这话是不是刚说的":每封信带序号与时间戳,收发双方各记一本"最近见过的编号"账,旧号重来一律拒收。

城墙最要紧的一块砖是消息认证码:发信方用只有双方知道的钥匙给信件内容算出一枚"火漆印",内容变一比特,火漆就对不上。它同时解决篡改检测与来源认证——没有钥匙的第三者既造不出合法火漆,也改不了带火漆的信。顺手把防重放也做进去:火漆覆盖的内容里掺进一次性随机编号。下面把这套流程完整跑一遍:

import hashlib, hmac, os def seal(msg: bytes, key: bytes) -> bytes: """邮局盖火漆:随机编号 8 字节 加 HMAC-SHA256 截短 8 字节。""" nonce = os.urandom(8) # 一次性编号 防重放 tag = hmac.new(key, nonce + msg, hashlib.sha256).digest()[:8] return nonce + tag def verify(msg: bytes, wax: bytes, key: bytes) -> bool: """收信方验火漆:用同样的钥匙重算一遍 比对是否一致。""" nonce, tag = wax[:8], wax[8:] expect = hmac.new(key, nonce + msg, hashlib.sha256).digest()[:8] return hmac.compare_digest(tag, expect) # 常量时间比较 防时序侧信道 key = b"town-post-office-secret" letter = b"bid: pave Main Street, price 500 coins" wax = seal(letter, key) print("原信验讫 :", verify(letter, wax, key)) # True tampered = b"bid: pave Main Street, price 5000 coins" print("改价信验讫 :", verify(tampered, wax, key)) # False forged = seal(tampered, b"attacker-key") # 骗子自配钥匙自盖火漆 print("假章验讫 :", verify(tampered, forged, key)) # False print("旧信重验 :", verify(letter, wax, key)) # True 但账房查 nonce 已见过 则拒收

输出三行True或False对应三种剧情:原信与火漆匹配通过;价格从五百改成五千,火漆立刻对不上;骗子自己配钥匙另盖的火漆同样对不上。最后一行点出认证码的边界——它只保证"信没被改过、出自持钥匙者",不保证"信是新的",所以工程上必须把 nonce 记账查重,两道工序缺一不可。还有一个容易省错的地方:比对必须用常量时间函数,逐字节早退的普通比较会通过耗时差泄露"对了几位",给攻击者递梯子。

户籍处的新规矩:差分隐私

城墙防的是外人,户籍处的难题是家贼与"合法泄密":统计报表本身就能咬人。差分攻击的原理值得亲手做一遍——攻击者知道其余九户的补助情况,只差一户未知;报表若如实公布总户数,做一次减法,未知户当场现形。差分隐私的思路不是藏报表,而是给报表加精心校准的噪声:任何单独一户改不改答案,分布几乎不动,于是一次查询泄不出单户信息,而总量层面的统计规律依然可读。噪声取拉普拉斯分布,尺度与隐私预算挂钩:预算 epsilon 越小,噪声越大,隐私越紧、报表越糊——这是隐私与效用的旋钮。

import random, math def laplace(rng, b): """标准拉普拉斯噪声 尺度 b。""" u = rng.random() - 0.5 return -b * math.copysign(math.log(1 - 2 * abs(u) + 1e-12), u) class CensusOffice: """户籍处:只发布加噪总数 任一户改口 报表分布几乎不动。""" def __init__(self, subsidies, eps=1.0, seed=11): self.data = list(subsidies) # 每户 1/0 是否领取补助 self.b = 1.0 / eps # 预算越小 噪声越大 self.rng = random.Random(seed) def report(self): return sum(self.data) + laplace(self.rng, self.b) town = [1, 0, 0, 1, 1, 0, 1, 0, 0, 1] # 十户中四户领取 office = CensusOffice(town, eps=1.0) accomplice_sum = sum(town[:-1]) # 攻击者握着九户底细 只差末户 print("真实总数 :", sum(town)) print("差分攻击读数 :", sum(town) - accomplice_sum, "(若报表不加噪 一击命中)") print("加噪后攻击样本 :", [round(office.report() - accomplice_sum, 2) for _ in range(5)]) print("加噪后官方口径 :", [round(office.report(), 2) for _ in range(5)])

跑出来看对比:不加噪时差分攻击读数稳稳落在 1——末户领取的事实精确泄露;加噪后同一攻击的读数在正负几之间乱跳,单户的一票被噪声淹没,而官方口径的加噪总数始终在真实值附近徘徊,宏观统计照常可用。使用纪律有两条:其一,预算按"全年所有查询"记账而非按单次,反复查询会把噪声平均掉,等价于变相去噪;其二,噪声尺度要按最坏单条记录的影响来定(本例单户影响 1,若统计的是收入总和,单户影响大,噪声须相应放大)。多智能体场景里这套思路的延伸是联邦式协作:各镇民只在本地算梯度、只上传奇扰后的更新,原始数据不出户——细节属于机器学习侧,此处立好"统计发布必有预算"的观念即可。

纵深防御:把散件拼成体系

单一防线都有失效条件,治安靠的是层层设防、相互补位。拼装的次序值得背下来:门禁层(认证与授权)把陌生人挡在外面;信道层(加密加认证码)保证说话路上不被动手脚;行为层(入侵检测)假设前两层已被部分打穿,盯着"这个镇民最近的行为离谱吗"——投标永远压到离谱低价、深夜高频发信、答复总在诱导别人先出手,异常模式交给统计或学习型监视者;制度层(第 3 章的规范与制裁、第 5 章的信誉扣分)把被抓包的劣迹变成未来待遇的折价,让攻击的长期成本高于短期收益;审计层(日志)保证事后能复盘、责任能追到户。

体系的精髓在箭头上:行为层的告警喂给制度层扣信誉,信誉又反过来收紧门禁的审查强度——安全从静态的墙变成会呼吸的闭环。另外两句提醒:安全强度要按最薄弱镇民配置,开放系统里你无法挑选队友,自己的防线必须假设邻居可能已经是傀儡;隐私同理,第 5 章的信用档案把镇民行为记了一路,档案本身就是高价值泄密目标,所以信用档案局自己也该吃差分隐私这副药。至于当下热门的大模型驱动智能体,提示注入、工具滥用等新型攻击面是另一册(《大模型驱动的智能体构建与应用》)的正题,本节给出的纵深分层在那里原样适用。

⚠️ 常见坑一:只砌镇门不砌宅门——以为入口认证了就万事大吉,而 MAS 里智能体互为环境,内部通信链路一样要认证加密,边界防御在开放系统里天然残废。坑二:把加密当认证——密文只防偷看,防篡改与防伪造必须靠消息认证码或签名,两者是不同的砖。坑三:隐私预算当无限额度花——同一份底表反复出报表,噪声在多次查询平均下越来越薄,差分攻击卷土重来;预算要全局记账、花完封表。

💡 关键直觉:安全机制的本质是机制设计(第 6 章的近亲)——不是把坏人挡在门外,而是让做坏人的收益结构变得不划算:冒名会被验出、改信会被识破、作恶会被信誉记账。设计任何防线时先问一句:这道防线改变了攻击者的哪一项收益?

沙盘推演小结

工坊三课至此齐备:选型给桌子(8.1)、方法论给尺子(8.2)、安全给墙与户籍(本节)。验收清单也顺手留下——身份进门先验、信件火漆必盖、编号查重防重放、报表发布必带预算、异常行为进信誉账。镇内治安至此成体系,下一章终于可以出镇,去看看真实街区里交通、电网、机器人与市场怎么把这套机制用出花来。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U