生日攻擊是密碼學的一種破譯手段,利用了機率論中的生日問題,用於干擾兩個或以上群體之間的通訊。此攻擊是對固定的重新排列模式作隨機嘗試攻擊,仰賴較高的命中率(鴿籠原理)。生日攻擊可在\sqrt{2^n} = 2^{n / 2}等級的時間內找到雜湊碰撞,低於原像攻擊的 2^n。有研究給出一個籠統(但尚存爭議)的估計,表示量子電腦能夠進行生日攻擊,進而可以破解防雜湊碰撞的抵禦,並能把時間壓縮到 \sqrt[3]{2^n} = 2^{n / 3} 的等級。
理解問題
舉例來說,假設有一位老師帶著一個有30位學生(n = 30)的班級,老師詢問每位學生的生日(為了簡化計算,忽略閏年),想要確認是否有兩位學生的生日相同(這相當於稍後會提到的雜湊碰撞)。 直覺上,這個機率可能看起來很小。 但出乎意料的是,根據公式 1-\frac{365!}{(365-n)!\cdot 365^n} 計算,至少有一位學生的生日與其他任一天的生日相同的機率(n = 30)約為70%。
如果老師挑選了一個特定的日期(例如 9 月 16 日),那麼至少有一位學生在該特定日期出生的機率是1 - (364/365)^{30},約7.9%。
在生日攻擊中,攻擊者會準備多個不同版本的良性和惡意合約,每個合約都有一個數位簽章。 目標是尋找一對具有相同簽章的良性和惡意合約。 在這個假設的例子中,假設字串的數位簽章是其SHA-256雜湊值的第一個位元組。 找到的組合將以綠色表示——需要注意的是,找到兩個良性合約(藍色)或兩個惡意合約(紅色)的配對是無效的的。 當受害者接受良性合約後,攻擊者會將其替換為惡意合約,並聲稱受害者已簽署該合約,因為數位簽章可以作為證據。
數學證明
定義函數f,攻擊目標是找到符合f(x_{1}) = f(x_{2})的兩个不同輸入值x_{1}, x_{2}。这一对x_{1}, x_{2}被稱之為碰撞。找出一對碰撞值的方法可以是隨機(或偽隨機地)輸入不同的數值,直到找出至少兩個相同的結果為止。但根據生日問題所述,其實有着更為高效的方法。明確地說,若函數f(x)所拥有的H的不同输出有着同等的可能性(即P(H_i)為常數)且H足够大,那麼,我們期望找到f(x_{1}) = f(x_{2})的一對不同的自變量x_{1}和x_{2},平均需要大約1.25\sqrt{H}个不同的自變量。
考慮以下的一个實驗;從下列的H數集中均匀、隨機地選擇n个值,因此將允许重複。設p(n; H)為此實驗中至少一个值被選擇多於一次的概率。則該概率可以以下數學形式表達:
: p(n;H) \approx 1 - e^{-n(n-1)/(2H)} \approx 1-e^{-n^2/(2H)}
設n(p; H)為將選擇的最小数值,这种情况下找到碰撞的概率至少為 p。通过颠倒上方的表达式,可得到下列估算公式:
: n(p;H)\approx \sqrt{2H\ln\frac{1}{1-p}}
又將碰撞概率設為0.5,將得到
: n(0.5;H) \approx 1.1774 \sqrt H
使Q(H)成为在尋找首次碰撞前所期望的值的数量,則該量可通过下列公式進行估算:
: Q(H)\approx \sqrt{\frac{\pi}{2}H}
舉例:若使用64位哈希,則估算將會有1.8 × 1019个不同的輸出。若這些輸出均可能發生(理想情况下),則攻擊者“僅僅”需要約50億次嘗試(5.38 × 109)就能通过暴力攻擊生成碰撞。此值被称为 生日界限(birthday bound)。而对于n位密码则需要2n/2次;下面列出其他例子
:
:上表展示了需要達到給定成功可能性的哈希數量n(p),且假設所有哈希值均有同等的出現概率。為了方便比較,通常一塊硬盘的不可修正位元(bit)錯誤率設為10−18至10−15。理論上,使用128位的MD5哈希或通用唯一识别码将在8200億份文档時得到破解,即使它們的可能輸出要比那數大得多。
顯然而見,若函数的輸出不平均分布,則碰撞可能更快被找到。哈希函數的“平衡”概念量化了其能抵御生日攻擊(攻擊不平均的密鑰分布)的次數。然而,確定哈希函數的平衡量將需要計算所有輸入,因此這種方法對於諸如MD及SHA系的流行哈希函數是不切實際的。
當計算n(p;H)中的子表达式\ln\frac{1}{1-p}的常見程序設計語言的翻譯版本時,例如log(1/(1-p)),公式由於,因而對於較小的p的計算精度不高。例如,在log1p(如C99中一样)和-log1p(-p)均可用時,後者應被選擇,而非較為不精確的前者。 如果不這樣做,上表的第一列将被计算为零,而對於第二列中的某幾項甚至没有一个正確的有效數字。
源碼示例
下列是能準確(大概)生成上方表格中大多數數值的Python函數:
from math import log1p, sqrt
def birthday(probability_exponent, bits):
probability = 10.0**probability_exponent
outputs = 2.0**bits
return sqrt(2.0outputs-log1p(-probability))
若代碼保存在命名為birthday.py的文件中,用户可像下面的例子一樣運行此程序:
$ python -i birthday.py
>>> birthday(-15, 128)
824963474247.1193
>>> birthday(-6, 32)
92.68192319417072
簡約估算
一項經驗法則可適用於此關係中的心算流程
:p(n) \approx {n^2 \over 2H}
可改寫為
:H \approx {n^2 \over 2p(n)}.
或
:n \approx \sqrt { 2H \times p(n)}.
此公式在概率小於等於0.5時有效。
該近似方案在使用指数时可輕易使用。例如,假设構建32位哈希(H = 2^{32})且希望碰撞概率为100万分之一( p \approx 2^{-20} ),需要的文檔數為
:n \approx \sqrt { 2 \times 2^{32} \times 2^{-20}} = \sqrt { 2^{1+32-20} } = \sqrt { 2^{13} } = 2^{6.5} \approx 90.5
即与正确答案93次近似。
數字簽章敏感度
數位簽章可對生日攻击十分敏感。設想一條被首次計算f(m)(f为密碼雜湊函數)所簽名的信息,且隨後又使用了一些密鑰来簽名f(m)。假設馬洛里想要使鮑勃簽上惡意合同;馬洛里准备了一份正常合同m和一份偽造合同m'。她隨後發現m的一些位置可在不改變原意的情况下(如插入逗號、清空行、在句號後增加一兩个空格、同義詞替換等等)被更改。通過組合这些更改,她可新建諸多m的變體且與該正常合同同義。
相似地,馬洛里也為偽造合同m'新建了諸多變體。她隨後使用哈希函数計算所有變體直到她找到與正常合同有着相同哈希值f(m) = f(m')的偽造合同版本。她隨後將正常合同該正常給鮑勃簽名。在鲍勃簽名後,馬洛里將該簽名複製至偽造合同上。該簽名“證實了”鮑勃簽署了該偽造合同。
在此例中,攻擊概率与原始的生日问题稍有不同,因為馬洛里在尋找兩份具有相同哈希的正常合同与偽造合同時一無所獲。馬洛里是為了生成一對哈希值相同的偽造和正常合同。生日問題公式適用于n為合同對數的情况下。但馬洛里所生成的哈希數實際上為2n。
為了避免這種攻擊,用於簽名方案的哈希函數的輸出長度應够大以從數學上防止生日攻擊。換言之,位數應為防止普通暴力破解所需位数的兩倍。
除了使用更大的位數長度外,簽名者(鮑勃)可以在簽名前做出一些隨機且無害的更改,並且在自己的手上留下一份合同副本以在法庭上展示出他的簽名与正常合同上的匹配,而不匹配偽造合同。
離散對數的波拉德ρ算法是使用生日攻擊以計算離散對數的算法。
另请参阅
*
- 中途相遇攻擊
脚注
参考文献
- ,《等一下:哈希函数平衡及其对生日攻击的影响》(Tadayoshi Kohno: Hash Function Balance and Its Impact on Birthday Attacks) 2004: pp401–418
- 《应用密码学》, 第二版。(Applied Cryptography, 2nd ed.) 布魯斯·施奈爾所著
外部链接
- [https://web.archive.org/web/20040913080209/http://www.rsasecurity.com/rsalabs/node.asp?id=2182 "What is a digital signature and what is authentication?"] 来自加密的常見問題集。
- [http://x5.net/faqs/crypto/q95.html "Birthday Attack"] X5网络加密问答
Kollisionsangriff#Geburtstagsangriff
评论 (0)