日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

哈希碰撞与生日攻击

發(fā)布時(shí)間:2025/3/21 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 哈希碰撞与生日攻击 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、哈希碰撞是什么?

所謂哈希(hash),就是將不同的輸入映射成獨(dú)一無二的、固定長度的值(又稱"哈希值")。它是最常見的軟件運(yùn)算之一。

如果不同的輸入得到了同一個(gè)哈希值,就發(fā)生了"哈希碰撞"(collision)。

舉例來說,很多網(wǎng)絡(luò)服務(wù)會(huì)使用哈希函數(shù),產(chǎn)生一個(gè) token,標(biāo)識(shí)用戶的身份和權(quán)限。

AFGG2piXh0ht6dmXUxqv4nA1PU120r0yMAQhuc13i8

上面這個(gè)字符串就是一個(gè)哈希值。如果兩個(gè)不同的用戶,得到了同樣的 token,就發(fā)生了哈希碰撞。服務(wù)器將把這兩個(gè)用戶視為同一個(gè)人,這意味著,用戶 B 可以讀取和更改用戶 A 的信息,這無疑帶來了很大的安全隱患。

黑客攻擊的一種方法,就是設(shè)法制造"哈希碰撞",然后入侵系統(tǒng),竊取信息。

二、如何防止哈希碰撞?

防止哈希碰撞的最有效方法,就是擴(kuò)大哈希值的取值空間。

16個(gè)二進(jìn)制位的哈希值,產(chǎn)生碰撞的可能性是 65536 分之一。也就是說,如果有65537個(gè)用戶,就一定會(huì)產(chǎn)生碰撞。哈希值的長度擴(kuò)大到32個(gè)二進(jìn)制位,碰撞的可能性就會(huì)下降到 4,294,967,296 分之一。

更長的哈希值意味著更大的存儲(chǔ)空間、更多的計(jì)算,將影響性能和成本。開發(fā)者必須做出抉擇,在安全與成本之間找到平衡。

下面就介紹,如何在滿足安全要求的前提下,找出哈希值的最短長度。

三、生日攻擊

哈希碰撞的概率取決于兩個(gè)因素(假設(shè)哈希函數(shù)是可靠的,每個(gè)值的生成概率都相同)。

  • 取值空間的大小(即哈希值的長度)
  • 整個(gè)生命周期中,哈希值的計(jì)算次數(shù)

這個(gè)問題在數(shù)學(xué)上早有原型,叫做"生日問題"(birthday problem):一個(gè)班級(jí)需要有多少人,才能保證每個(gè)同學(xué)的生日都不一樣?

答案很出人意料。如果至少兩個(gè)同學(xué)生日相同的概率不超過5%,那么這個(gè)班只能有7個(gè)人。事實(shí)上,一個(gè)23人的班級(jí)有50%的概率,至少兩個(gè)同學(xué)生日相同;50人班級(jí)有97%的概率,70人的班級(jí)則是99.9%的概率(計(jì)算方法見后文)。

這意味著,如果哈希值的取值空間是365,只要計(jì)算23個(gè)哈希值,就有50%的可能產(chǎn)生碰撞。也就是說,哈希碰撞的可能性,遠(yuǎn)比想象的高。實(shí)際上,有一個(gè)近似的公式。

上面公式可以算出,50% 的哈希碰撞概率所需要的計(jì)算次數(shù),N 表示哈希的取值空間。生日問題的 N 就是365,算出來是 23.9。這個(gè)公式告訴我們,哈希碰撞所需耗費(fèi)的計(jì)算次數(shù),跟取值空間的平方根是一個(gè)數(shù)量級(jí)。

這種利用哈希空間不足夠大,而制造碰撞的攻擊方法,就被稱為生日攻擊(birthday attack)。

四、數(shù)學(xué)推導(dǎo)

這一節(jié)給出生日攻擊的數(shù)學(xué)推導(dǎo)。

至少兩個(gè)人生日相同的概率,可以先算出所有人生日互不相同的概率,再用 1 減去這個(gè)概率。

我們把這個(gè)問題設(shè)想成,每個(gè)人排隊(duì)依次進(jìn)入一個(gè)房間。第一個(gè)進(jìn)入房間的人,與房間里已有的人(0人),生日都不相同的概率是365/365;第二個(gè)進(jìn)入房間的人,生日獨(dú)一無二的概率是364/365;第三個(gè)人是363/365,以此類推。

因此,所有人的生日都不相同的概率,就是下面的公式。

上面公式的 n 表示進(jìn)入房間的人數(shù)。可以看出,進(jìn)入房間的人越多,生日互不相同的概率就越小。

這個(gè)公式可以推導(dǎo)成下面的形式。

那么,至少有兩個(gè)人生日相同的概率,就是 1 減去上面的公式。

五、哈希碰撞的公式

上面的公式,可以進(jìn)一步推導(dǎo)成一般性的、便于計(jì)算的形式。

根據(jù)泰勒公式,指數(shù)函數(shù) ex?可以用多項(xiàng)式展開。

如果 x 是一個(gè)極小的值,那么上面的公式近似等于下面的形式。

現(xiàn)在把生日問題的1/365代入。

因此,生日問題的概率公式,變成下面這樣。

假設(shè) d 為取值空間(生日問題里是 365),就得到了一般化公式。

上面就是哈希碰撞概率的公式。

六、應(yīng)用

上面的公式寫成函數(shù)。

const calculate = (d, n) => {const exponent = (-n * (n - 1)) / (2 * d)return 1 - Math.E ** exponent; }calculate(365, 23) // 0.5000017521827107 calculate(365, 50) // 0.9651312540863107 calculate(365, 70) // 0.9986618113807388

一般來說,哈希值由大小寫字母和阿拉伯?dāng)?shù)字構(gòu)成,一共62個(gè)字符(10 + 26 + 26)。如果哈希值只有三個(gè)字符的長度(比如abc),取值空間就是?62 ^ 3 = 238,328,那么10000次計(jì)算導(dǎo)致的哈希碰撞概率是100%。

calculate(62 ** 3, 10000) // 1

哈希值的長度增加到5個(gè)字符(比如abcde),碰撞的概率就下降到5.3%。

calculate(62 ** 5, 10000) // 0.05310946204730993

現(xiàn)在有一家公司,它的 API 每秒會(huì)收到100萬個(gè)請求,每個(gè)請求都會(huì)生成一個(gè)哈希值,假定這個(gè) API 會(huì)使用10年。那么,大約一共會(huì)計(jì)算300萬億次哈希。能夠接受的哈希碰撞概率是1000億分之一(即每天發(fā)生一次哈希碰撞),請問哈希字符串最少需要多少個(gè)字符?

根據(jù)上面的公式倒推,就會(huì)知道哈希值的最短長度是22個(gè)字符(比如BwQ1W6soXkA1PU120r0yMA),計(jì)算過程略。

22個(gè)字符的哈希值,就能保證300萬億次計(jì)算里面,只有1000億分之一的概率發(fā)生碰撞。常用的 SHA256 哈希函數(shù)產(chǎn)生的是64個(gè)字符的哈希值,每個(gè)字符的取值范圍是0~9和a~f,發(fā)生碰撞的概率還要低得多。

七、參考鏈接

  • How Long Should I Make My API Key?, by Sam Corcos
  • Birthday problem, by Wikipedia
  • Birthday attack, by Wikipedia

總結(jié)

以上是生活随笔為你收集整理的哈希碰撞与生日攻击的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。