最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

「密碼學」哈希為什么要將鹽加在明文后面?

2023-03-10 17:31 作者:Swhites  | 我要投稿

眾所周知,在做消息認證或者簽名時,僅使用hash函數(shù)安全性是不高的,容易遭受字典和暴力破解(https://www.cmd5.com/)。所以通常會使用帶密鑰或加鹽的哈希算法作為消息認證或者口令存儲,正如標題所說,我們在檢索互聯(lián)網(wǎng)上關于加鹽的實現(xiàn)時,內容往往都是在明文后面加上隨機值:

image-20230307141942058

那做消息認證的密鑰或者鹽可不可以加在明文前面呢?

這就引出本文的攻擊方式。

MD5 算法計算邏輯

為了清楚這個攻擊方式原理,需要先了解下md5的計算邏輯。

md5算法本質上是一種壓縮算法,將長度小于2^64bit的任意字符壓縮成128bit固定長度字符。同AES之類的分組加密算法一樣,md5也需要進行分組計算。

圖來自先知社區(qū)

如圖所示,md5的計算需要經(jīng)過兩個步驟:

  1. 分組&填充

  2. 具體計算

1.分組&填充

首先會對明文按照512bit的長度進行分組,最后一個分組可能會發(fā)生長度不足512bit,或者剛剛512bit。

無論最后一個分組的長度是否剛好等于512bit,按照填充規(guī)則都需要進行填充,具體細節(jié):

  • 假設明文剛好能被512整除,需要新增一個分組,在末尾8*8=64bit 按照小端存儲放入原始明文的長度,分組中間剩余的bit 按照10000000的方式進行填充,形成一個總長512bit的新分組。

  • 假設整除512bit余數(shù)大于0

    • 且余數(shù)大于512-8*8 =448 bit 則需要繼續(xù)填充10000(0x80000.....)至下一個分組的448bit,剩余的bit按照小端存儲填充原始明文長度

    • 余數(shù)小于448bit,末尾填充原始明文長度,中間剩余部分填充填充10000(0x80000.....)

以上兩個步驟用代碼表示即為:

1 ? ? ? ?m_l = len(message) ?# 原始消息長度2 ? ? ? ?length = struct.pack('<Q', (m_l) * 8) ?# 長度轉化為小端 unsigned long long 8B3 ? ? ? ?blank_padding = b""4 ? ? ? ?message += b'\x80' ?# 100000005 ? ? ? ?# 此分組不足以填充長度時6 ? ? ? ?if 56 < len(message) < 64:7 ? ? ? ? ? ?blank_padding += b'\x00' * (56 + 64 - len(message)) ?# 填充至下一個分組8 ? ? ? ?# 分組能填充長度9 ? ? ? ?else:10 ? ? ? ? ? ?blank_padding = b'\x00' * (56 - len(message) % 64) ?# 本分組填充11 ? ? ? ?if len(blank_padding) > 0:12 ? ? ? ? ? ?# 填充1000013 ? ? ? ? ? ?message += blank_padding14 ? ? ? ?# 填充長度15 ? ? ? ?message += length

2. 具體計算

其實具體的計算過程,我們不用關注,把這個過程當做一個黑盒(關注細節(jié)的可以關注文末github地址)就可以:

image-20230309111335844

在上一步分組的基礎上,第一組的分組的明文會和128bit的初始序列(幻數(shù))做為輸入進行壓縮計算,初始序列是一組固定的值:

image-20230309174432910

計算后會產(chǎn)生新的序列,做為下一組的“初始序列”和下一組的明文再次進行壓縮計算,接下來的分組重復這種“上一組的輸出作為下一組的輸入”,最后一組的128bit輸出即為最終的md5值。

哈希長度拓展攻擊

了解了md5的計算邏輯,再回到這張圖,上一次的的輸出作為下一次的輸入這種方式可能會導致一個問題。假設存在明文分組abc,明文分組產(chǎn)生md5的過程可以簡化為:

  • 分組a:h.a = md5(iv,a), md5計算需要兩個參數(shù),iv 為初始序列,h.a 為壓縮計算結果

  • 分組b:h.ab = md5(h.a,b)

  • 分組c或者最終md5: h.abc = md5(h.ab,c)

圖來自先知社區(qū)

在這個過程當中,如果密鑰被放在a分組當中,bc為原消息認證的明文,那攻擊者可以在不知道密鑰的情況下,擴展明文長度,如增加明文d,計算abcd的hash,只需要知道基于abc的hash值,即可生成新的hash。

即:h.abcd = md5(h.abc,d)

這個過程即為hash長度擴展攻擊。

接下來我們根據(jù)實際的例子來實操下

實操

假設存在一個商城訂單支付場景,訂單的確認是通過前端參數(shù)給出,存在一個邏輯漏洞可以通過前端參數(shù)來控制商品價格,從而實現(xiàn)“零元購”或者越權購買。

image-20230307165648656

正常情況下進行購買,因為默認此用戶只有300積分,所以會購買失?。?/p>

image-20230307171050046

但如果進行參數(shù)價格good_price修改,會因為簽名校驗不通過:

image-20230307171601458

所以需要進行簽名破解,先看下后端驗證的邏輯:

1<?php2 $total_score = 300;3 $flag = 'xxxxxxxxxxxx';4 $secret_key = "??????????????????????????????????????"; ?// 前端未知5 $post_data =urldecode(file_get_contents("php://input"));6 $user_sign = $_GET['signature'];7 $sign = md5($secret_key.$post_data);8 if ($user_sign === $sign) {9 ?$price = $_POST['good_price'];10 ?if ($price > $total_score){11 ? echo '對不起,您的積分余額不足,交易失?。?#39;;12 ?}else{13 ? echo "恭喜,購買成功!$flag";14 ?}15 }else{16 ?echo '簽名數(shù)據(jù)被篡改!';17 }1819?>

后端存在一個簽名邏輯,會驗證用戶的post參數(shù)加上密鑰的md5值,如果用戶修改了post參數(shù),但因為不知道密鑰也就沒發(fā)生成合法的md5,所以驗證會不通過。

如果沒有了解過哈希長度擴展攻擊,這個代碼是沒啥問題的,所以知識面決定攻擊面。

而且這個地方密鑰被放在了明文前面拼接,針對哈希長度擴展攻擊,利用起來還挺簡單的,可以使用現(xiàn)成的工具,比如hashpump,按照提示輸入內容即可:

image-20230310154439762

最后的明文中十六進制部分需要url編碼,但因為hashpump需要編譯,在win平臺編譯比較麻煩,所以我自己實現(xiàn)了一個md5版本的利用工具(https://github.com/shellfeel/hash-ext-attack

image-20230310161015225

最后把得到的結果粘貼到burp,成功購買。

image-20230310164429827

總結

文章分析了下md5的計算邏輯,以及哈希長度擴展的攻擊原理,對于此類攻擊的修復,其實很簡單只需要把密鑰由加在明文前面改為明文后面,或者使用標準的hmac算法,hmac算法里面會用密鑰和明文做移位異或操作,從而增強hash的安全性,本文是以md5為例,其實對于有著類似M-D結果的hash算法都是可以這樣利用的,比如sha-0,sha-1,sha-2 等。

image-20230301201336027


參考

  • 《白帽子講web安全》

  • 先知社區(qū)

  • hashpump

公眾號

歡迎大家關注我的公眾號,這里有干貨滿滿的硬核安全知識,和我一起學起來吧!

歡迎關注


「密碼學」哈希為什么要將鹽加在明文后面?的評論 (共 條)

分享到微博請遵守國家法律
梨树县| 鹤岗市| 通海县| 定州市| 漠河县| 铁岭县| 义马市| 沈阳市| 剑河县| 家居| 丽江市| 霍林郭勒市| 永定县| 绍兴市| 阳城县| 苏尼特左旗| 广州市| 合江县| 沭阳县| 中方县| 阿克| 宁武县| 进贤县| 丹阳市| 门源| 房山区| 余干县| 连平县| 堆龙德庆县| 涞水县| 衡阳县| 芒康县| 大庆市| 财经| 松江区| 南康市| 巨野县| 普兰店市| 内江市| 团风县| 玉林市|