針對EdDSA的fault attack
最近比賽繁多,抽時間看了一下EdDSA簽名的有關內容,正好碰到一道題目涉及了對其的故障攻擊,確實非常有意思,就在這裡記錄一下
EdDSA簽名
EdDSA也是基於ECC的簽名演算法,平常我們見的比較多的應該是ECDSA簽名,比如比特幣使用的基於曲線secp256k1的ECDSA簽名,以及基於NIST選擇的幾條曲線的簽名等等
不過NIST P-256曲線,也就是secp256r1,因為預設使用的Dual_EC_DRBG隨機數生成器一直被懷疑存在NSA隱藏的後門,到了13年斯諾登的曝光更是將這件事推上了風口浪尖,所以大家也就失去了對這一演算法的信任,所以當年比特幣選擇了比較小眾的secp256k1曲線還是有自己的考量
另外,我想熟悉ECDSA簽名的朋友應該也都知道ECDSA簽名演算法的安全性是比較依賴於安全的隨機數生成演算法的,如果隨機數演算法存在問題,使用了相同的k進行簽名,那麼攻擊者是可以根據簽名信息恢復私鑰的,歷史上也出過幾次這樣的事故,比如10年索尼的PS3私鑰遭破解以及12年受java某隨機數生成庫的影響造成的比特幣被盜事件,關於這部分內容我也寫過相關的分析,可以參見 ofollow,noindex" target="_blank">利用隨機數衝突的ECDSA簽名恢復以太坊私鑰 ,所以說ECDSA簽名在設計上還是存在一些問題的, 這也激勵了新的EdDSA演算法的出現
EdDSA簽名演算法由Schnorr簽名發展變化而來,可以在 RFC8032 中看到它的定義實現,由曲線和引數的選擇不同又可以劃分為Ed25519和Ed448演算法,顧命思義,它們兩分別是基於curve25519和curve448曲線,一般用的比較多的是Ed25519演算法,相比Ed448而言運算速度要更快,祕鑰與簽名空間也較小,二者的使用場景還是有點區別,下面我們主要講的也是Ed25519
Ed25519所使用的曲線由curve25519變換而來,curve25519是蒙哥馬利曲線,經過變換得到Ed25519使用的扭愛德華曲線edwards25519,curve25519曲線的安全性是非常高的,可以在 safecurves 檢視各橢圓曲線的安全指標,curve25519是其中為數不多所有指標都達標的曲線,curve25519常用於金鑰交換的DH演算法
而且EdDSA的運算速度也比ECDSA演算法要快很多,優勢可以說是非常明顯的,門羅幣和zcash等加密貨幣已經將演算法切換到了EdDSA了,目前其也被確認為下一代橢圓曲線演算法
Ed25518所取的有限域P跟curve25519相同,都是2^255-19,這也是這一曲線的名字由來,還有很多其他引數如公私鑰的長度,選取的基點B等,在不同情況下也有不同的選擇,Ed25519中也可做進一步的劃分,只要滿足rfc文件的定義即可,更多引數的定義可以參考 rfc7748
下面我們來看看Ed25519的具體簽名過程,相比ECDSA確實有很大區別
Ed25519的私鑰k長度為b bit,一般是256,其使用的hash演算法H的輸出長度為2b bit,一般選擇的是SHA512,對應b等於256
首先,對私鑰k進行hash,得到
使用hash的結果我們可以計算得到引數a
這樣我們就可以得到私鑰k對應的公鑰A,A=aB,B為選取的基點,下面我們準備對訊息M進行簽名,過程如下,其中l為基點B的階
這樣就得到了訊息M的簽名(R,S),簽名的驗證則需滿足下面的等式
觀察整個簽名過程,我們不難發現,一個私鑰k,當對同一個訊息M進行簽名時R與S都是固定的,所以說EdDSA是一種確定性的簽名演算法,不像ECDSA那樣每次簽名都根據選取的隨機送的變化而不同,所以EdDSA的安全性也就不再依賴於隨機數生成器
Ed25519的實現程式可以參考這裡, Ed25519 software ,用python實現的,還是挺有意思
fault attack
下面我們簡單介紹一下fault attack也就是故障攻擊,更確切地說我們也可以叫它 差分錯誤分析(Differential fault analysis) ,算是側通道攻擊的一種,主要針對包含處理器的智慧卡,手法是通過物理方法,如電磁輻射,鐳射等干擾密碼晶片的正常工作,迫使其執行某些錯誤的操作,依據錯誤的資訊能夠有效推算出密碼系統的金鑰資訊
其實故障攻擊的出現也是一場意外,科學家在研究時發現一塊晶片的敏感區域在遭受放射性的照射後出現了位元位翻轉的現象,從而引發了故障,但是通過分析這些資訊卻給我們打開了新世界的大門
引發故障的手法有很多種,比較簡單的像是改變電壓與溫度,修改時鐘頻率,高階點的像是電磁輻射,鐳射照射等,還有一些對應的防禦手段及應對的演算法,這裡就不展開了,有興趣的可以看看這篇論文, A SURVEY ON FAULT ATTACKS
相對而言比較出名的應該是針對RSA簽名的故障攻擊,為提高RSA處理資料的速度,Quisquater等人利用中國剩餘定理改進了RSA演算法的運算速度,即CRT-RSA演算法,不過這也為故障攻擊的分析提供了絕佳的入口,感興趣的可以看看這篇文章, RSA 簽名故障分析
另外,DES和AES也早已有對應的攻擊方式被提出,對於ECC的故障攻擊也已經有了很多的研究,fault attack的威脅還是非常大的,而且攻擊的方式其實也是非常巧妙
因為ECC演算法對應的金鑰空間較小,加之新的EdDSA的運算速度也比較快,所以在智慧卡領域ECC也已經有了很多的應用,對應的故障攻擊的威脅也就需要得到重視
下面我們就來看看針對Ed25519的故障攻擊
fault attack on EdDSA
這部分內容主要是基於Kudelski的這篇研究, HOW TO DEFEAT ED25519 AND EDDSA USING FAULTS
前面我們也提到了EdDSA簽名的特點是對於同一訊息M,不論你對它簽名多少次,得到的簽名結果都是相同的,那麼我們的fault attack也正是針對這一特性
在上面的前面過程中,假設我們針對第四步的hash過程進行攻擊,這樣就得到了一個錯誤的h值,即h’,由它計算得到的就是錯誤的簽名值S’,那麼根據關係我們就可以得到
要求出a,在上式中只有h’是未知的,那麼我們如何知道h’的值呢,其實很簡單,也就是爆破,關鍵在於我們要想辦法在攻擊時讓hash計算得到的結果中某一位進行翻轉,具體哪一位是未知的,翻轉的結果也是未知的,所以我們就進行逐位元組的爆破,在這裡假設使用的演算法中得到的h是32位元組的,那麼爆破過程可以用下面的偽程式碼表示,這也是借用了Kudelski的圖
過程還是很好理解的,那麼成功得到h’的值以後我們就可以計算得到a了,然而這時候你再看就會發現貌似知道了a也跟私鑰沒啥聯絡啊,進行簽名的第一步我們得知道私鑰的hash的後b位才能跟我們想簽署的訊息M生成新的h
其實這裡利用的就是EdDSA簽名的特點,也是這個故障攻擊最巧妙的地方,我們不妨隨機選擇一個r值,不用管簽名第一步計算的h,然後使用這個r完成下面的簽名過程,得到了簽名(R,S),然後進行簽名校驗
仔細檢視整個推導過程,我們不難發現哪怕我們選擇的r只是個隨機值,但是簽名的驗證仍然是可以通過的,也就是說只要知道了a的值我們就可以進行簽名的偽造了,並不需要知道原本的私鑰,其實這裡a已經可以看作是私鑰了
可以看到對EdDSA進行故障攻擊的過程是非常有趣的,以前提出的很多針對ECDSA的故障攻擊多是針對運算過程中的基點進行攻擊,比如讓它的座標發生改變,這樣對應的基點的階也將發生改變,很可能從一個大素數變成了一個大合數,而橢圓曲線的安全性要求基點的階是素數,所以攻擊後演算法所使用的橢圓曲線其實以及不再安全了,很可能遭受演算法如Pohlig-Hellman的攻擊,這個我之前也寫過相關的介紹, 簡析ECC攻擊方法之Pohlig-Hellman
最近Kudelski自己舉辦了一場crypto的ctf,其中就有一道題目是關於Ed25519的fault attack,下面我們就一起來看看
fault attack challenge
比賽詳情在這裡, https://github.com/kudelskisecurity/cryptochallenge18
涉及的題目是challenge1,題目給了四個api,如下
sign將返回我們傳送的data的簽名,我們來看看簽名的情況
很有意思,簽名的值在變化,其中穿插著一些錯誤的簽名,重複出現的應該就是正確的簽名了,不過觀察那些錯誤的簽名我們發現它們跟正確簽名的R與S都不同,如果按照我們前面介紹的故障攻擊的結果,那麼應該是R相同而S不同,那麼顯然這裡跟前面是不一樣的,此處使用的fault attack是簽名過程中第一步的hash值h進行了攻擊,這樣後面得到的R與S都是錯誤的,其實這樣反而更簡單了
回顧前面a的計算,當時我們未知的數是h’,但是在這裡h’我們是可以直接通過錯誤的簽名中的R’計算出來,所以說直接是已知的,那麼我們就可以直接計算得到a了
檢視一下我們需要簽名的訊息
完整的指令碼可以參考Ledger-Donjon團隊的 指令碼 ,以及他們的 write up ,其中的公鑰可以通過計算得到的a跟基點B計算得到
寫在最後
這次的研究讓我又學到了不少新的東西,深切體會到了知識面的重要性,以前對於EdDSA都沒什麼瞭解,不過目前的趨勢已經是在轉向確定性簽名機制了,EdDSA作為其中的代表自然是非常重要的,畢竟它的安全性和速度有目共睹
文章參考了很多的資料,就不一一列舉了,重要的資料我都在文中添加了連結,同時水平有限,可能有些地方沒寫好甚至是出現錯誤,還希望師傅們多多指教