协议(4)

真正的协议漏洞通常要比这种密码学方面的漏洞更容易攻击,至少2家厂商都犯了一个错误——?只检查Nonce与上次发送的是否相同,由此,假设给定两个有效码A和B,则序列ABABAB…就被视为一系列独立的有效码。对于车锁,小偷只要重放倒数第二个码,就可以把门打开。另外还有一个预付费仪表的例子,英国的一百多万个家庭,加上发展中国家的数百万的家庭,都安装了可接受加密令牌的电表和煤气表,这样,把加密卡牌买回家插到表里就可以使用相应数量的电和煤气。在南非,有一种广泛使用的电表只检查解密命令中的Nonce是否与上次相同。这样的话,顾客买两个小额电票,再反复地交替使用,就可以充电到最高值[59]。

因此,使用随机数还是计数器,这个问题并不像看起来那么简单[316]。如果使用随机数,锁必须记住前面很多个码,人也必须记住,以防止随从攻击(valet attack),这种攻击中,某些具备令牌临时访问权限的人(比如代客泊车的服务员)可以记录下很多访问码,之后进行重放以偷走你的车。如果需要记住数百个甚至数千个旧码,可能就需要足够的非易失性存储机制,比如价格不菲的微控制器,这难免要为你的锁增加一些成本。

如果愿意使用计数器,那么就要面对同步问题。一把钥匙可用在多把锁上,受口袋中物品挤压时也可能激活(有一次我把实验令牌带回家,结果因为被狗咬而激活了)。因此,如果计数器递增了几百甚至几千次以后,就必须有复位机制。如果在一定条件下让锁向钥匙“学习”,或与其保持同步,这就可以转化为优势,但是细节一般都设计得不完善。普通的产品使用16位计数器,只要译码以后计数器的值比最后一次使用时增加了不到16就可以访问。有时钥匙在别处使用了(或者被宠物抓到)16次以上,为了处理这种情况,倘若比起上次输入有效码时增加的值是17~32 767,锁就打开第二个区间(计数器采用循环方式,65 535的下一个数是0)。在很多应用程序中,上述处理方式可以有效工作,但实际上,攻击者只需要获取6个选定的访问码——?比如0、1、20 000、20 001、40 000和40 001,就可以完全突破系统。因此,必须仔细斟酌威胁模型中是否包含可以获取访问码(与选定计数器值相对应)的主体——?他可以耐心等待时机,也可以通过硬件攻击方式实现这一目的。

一个近期的设计失败实例来自TinyOS,这是一个用在传感器网络(基于IEEE 802.15.4 ad-hoc网络标准)中的操作系统。常用的TinySec库(用于安全协议)中包含3个计数器(而不是1个),第1个因为被无线射频芯片驱动程序重写而丢失,第2个没有被接收方记住,而尽管第3个可以正常工作,但该计数器用于保障可靠性而非安全性,因此,如果有人对流量进行篡改,则输出将是“错误”而非“警告”,而网络也将在错误计数器的作用下失去同步[340]。

因此,即便设计一个简单的令牌身份验证机制也并非那么简单。有很多种攻击方法并不需要“破坏”加密机制。随着加密身份验证机制的使用日益增加(负责设计和实现身份验证机制的很多程序员都把问题看得过于简单,例如连阅读本书这样的事情都不愿意去做),这类攻击会变得很常见。

另一个关于身份验证的重要实例是“附件控制”。很多打印机厂商在打印机中嵌入了身份验证机制,以便保证其打印机使用原装的墨盒。如果打印机被装载了竞争对手的产品,打印机的分辨率就会从1200dpi降到300dpi,或者干脆拒绝工作。移动电话的一大部分利润来自于充电电池,其中也使用了身份验证协议,以便识别竞争对手的产品,使其无法工作,甚至让它消耗得更快。其他相关行业也都逐渐开始采用这些机制,在汽车马达贸易中,有言论要求对主要的备用部件进行身份验证。第22章将和版权与权限管理一起对这些问题进行深入讨论,这里,我只想说安全机制正越发广泛地应用于商业模型,包括附件控制、权限管理、产品绑定与集成等。盲目地认为只要有安全协议就一定能“御敌于外”的想法是错误的。安全机制正日益广泛地用于对设备(安全机制构建在其中)的合法拥有者进行约束,其目的可能存在法律上的疑点或与公开策略相反。

读书导航