真正的協(xié)議漏洞通常要比這種密碼學方面的漏洞更容易攻擊,至少2家廠商都犯了一個錯誤——?只檢查Nonce與上次發(fā)送的是否相同,由此,假設給定兩個有效碼A和B,則序列ABABAB…就被視為一系列獨立的有效碼。對于車鎖,小偷只要重放倒數(shù)第二個碼,就可以把門打開。另外還有一個預付費儀表的例子,英國的一百多萬個家庭,加上發(fā)展中國家的數(shù)百萬的家庭,都安裝了可接受加密令牌的電表和煤氣表,這樣,把加密卡牌買回家插到表里就可以使用相應數(shù)量的電和煤氣。在南非,有一種廣泛使用的電表只檢查解密命令中的Nonce是否與上次相同。這樣的話,顧客買兩個小額電票,再反復地交替使用,就可以充電到最高值[59]。
因此,使用隨機數(shù)還是計數(shù)器,這個問題并不像看起來那么簡單[316]。如果使用隨機數(shù),鎖必須記住前面很多個碼,人也必須記住,以防止隨從攻擊(valet attack),這種攻擊中,某些具備令牌臨時訪問權限的人(比如代客泊車的服務員)可以記錄下很多訪問碼,之后進行重放以偷走你的車。如果需要記住數(shù)百個甚至數(shù)千個舊碼,可能就需要足夠的非易失性存儲機制,比如價格不菲的微控制器,這難免要為你的鎖增加一些成本。
如果愿意使用計數(shù)器,那么就要面對同步問題。一把鑰匙可用在多把鎖上,受口袋中物品擠壓時也可能激活(有一次我把實驗令牌帶回家,結果因為被狗咬而激活了)。因此,如果計數(shù)器遞增了幾百甚至幾千次以后,就必須有復位機制。如果在一定條件下讓鎖向鑰匙“學習”,或與其保持同步,這就可以轉化為優(yōu)勢,但是細節(jié)一般都設計得不完善。普通的產品使用16位計數(shù)器,只要譯碼以后計數(shù)器的值比最后一次使用時增加了不到16就可以訪問。有時鑰匙在別處使用了(或者被寵物抓到)16次以上,為了處理這種情況,倘若比起上次輸入有效碼時增加的值是17~32 767,鎖就打開第二個區(qū)間(計數(shù)器采用循環(huán)方式,65 535的下一個數(shù)是0)。在很多應用程序中,上述處理方式可以有效工作,但實際上,攻擊者只需要獲取6個選定的訪問碼——?比如0、1、20 000、20 001、40 000和40 001,就可以完全突破系統(tǒng)。因此,必須仔細斟酌威脅模型中是否包含可以獲取訪問碼(與選定計數(shù)器值相對應)的主體——?他可以耐心等待時機,也可以通過硬件攻擊方式實現(xiàn)這一目的。
一個近期的設計失敗實例來自TinyOS,這是一個用在傳感器網(wǎng)絡(基于IEEE 802.15.4 ad-hoc網(wǎng)絡標準)中的操作系統(tǒng)。常用的TinySec庫(用于安全協(xié)議)中包含3個計數(shù)器(而不是1個),第1個因為被無線射頻芯片驅動程序重寫而丟失,第2個沒有被接收方記住,而盡管第3個可以正常工作,但該計數(shù)器用于保障可靠性而非安全性,因此,如果有人對流量進行篡改,則輸出將是“錯誤”而非“警告”,而網(wǎng)絡也將在錯誤計數(shù)器的作用下失去同步[340]。
因此,即便設計一個簡單的令牌身份驗證機制也并非那么簡單。有很多種攻擊方法并不需要“破壞”加密機制。隨著加密身份驗證機制的使用日益增加(負責設計和實現(xiàn)身份驗證機制的很多程序員都把問題看得過于簡單,例如連閱讀本書這樣的事情都不愿意去做),這類攻擊會變得很常見。
另一個關于身份驗證的重要實例是“附件控制”。很多打印機廠商在打印機中嵌入了身份驗證機制,以便保證其打印機使用原裝的墨盒。如果打印機被裝載了競爭對手的產品,打印機的分辨率就會從1200dpi降到300dpi,或者干脆拒絕工作。移動電話的一大部分利潤來自于充電電池,其中也使用了身份驗證協(xié)議,以便識別競爭對手的產品,使其無法工作,甚至讓它消耗得更快。其他相關行業(yè)也都逐漸開始采用這些機制,在汽車馬達貿易中,有言論要求對主要的備用部件進行身份驗證。第22章將和版權與權限管理一起對這些問題進行深入討論,這里,我只想說安全機制正越發(fā)廣泛地應用于商業(yè)模型,包括附件控制、權限管理、產品綁定與集成等。盲目地認為只要有安全協(xié)議就一定能“御敵于外”的想法是錯誤的。安全機制正日益廣泛地用于對設備(安全機制構建在其中)的合法擁有者進行約束,其目的可能存在法律上的疑點或與公開策略相反。