一、什么是彩虹表?
彩虹表(Rainbow Tables)就是一個龐大的、針對各種可能的字母組合預先計算好的哈希值的集合,不一定是針對MD5算法的,各種算法的都有,有了它可以快速的破解各類密碼。越是復雜的密碼,需要的彩虹表就越大,現在主流的彩虹表都是100G以上。
二、上哪找彩虹表去?
現在有很多大牛已經把自己的彩虹表共享出來了,所以你可以去下載。還有一種方法就是自己通過工具生成。
不過自己生成有點不切合實際,生成小的彩虹表吧數據少,可以破解密碼的位數少(復雜程度低),而且費時費力,4核4GB內存的機器,生成2GB彩虹表,需要花費7天時間,而7天按1MB的帶寬(160K/S左右)幾乎可以下載30GB左右。
生成的工具可以用RainbowCrack也可以用Cain。網上很容易搜索到下載地址的。
加鹽值可以抵抗彩虹表攻擊 ,最好每次使用的鹽值要動態生成.
我們知道,如果直接對密碼進行散列,那么黑客可以對通過獲得這個密碼散列值,然后通過查散列值字典(例如MD5密碼破解網站),得到某用戶的密碼。
加Salt可以一定程度上解決這一問題。所謂加Salt方法,就是加點“佐料”。其基本想法是這樣的:當用戶首次提供密碼時(通常是注冊時),由系統自動往這個密碼里撒一些“佐料”,然后再散列。而當用戶登錄時,系統為用戶提供的代碼撒上同樣的“佐料”,然后散列,再比較散列值,已確定密碼是否正確。
這里的“佐料”被稱作“Salt值”,這個值是由系統隨機生成的,並且只有系統知道。這樣,即便兩個用戶使用了同一個密碼,由於系統為它們生成的salt值不同,他們的散列值也是不同的。即便黑客可以通過自己的密碼和自己生成的散列值來找具有特定密碼的用戶,但這個幾率太小了(密碼和salt值都得和黑客使用的一樣才行)。
下面以PHP示例,講解md5($pass.$salt)加密函數。
<?php
function hash($a) {
$salt=”Random_KUGBJVY”; //定義一個salt值,程序員規定下來的隨機字符串
$b=$a.$salt; //把密碼和salt連接
$b=md5($b); //執行MD5散列
return $b; //返回散列
}
?>
調用方式:$new_password=hash($_POST[password]); //這里接受表單提交值,並進行加密
下面詳細介紹一下加Salt散列的過程。介紹之前先強調一點,前面說過,驗證密碼時要使用和最初散列密碼時使用“相同的”佐料。所以Salt值是要存放在數據庫里的。
用戶注冊時,
- 用戶輸入【賬號】和【密碼】(以及其他用戶信息);
- 系統為用戶生成【Salt值】;
- 系統將【Salt值】和【用戶密碼】連接到一起;
- 對連接后的值進行散列,得到【Hash值】;
- 將【Hash值1】和【Salt值】分別放到數據庫中。
用戶登錄時,
- 用戶輸入【賬號】和【密碼】;
- 系統通過用戶名找到與之對應的【Hash值】和【Salt值】;
- 系統將【Salt值】和【用戶輸入的密碼】連接到一起;
- 對連接后的值進行散列,得到【Hash值2】(注意是即時運算出來的值);
- 比較【Hash值1】和【Hash值2】是否相等,相等則表示密碼正確,否則表示密碼錯誤。
有時候,為了減輕開發壓力,程序員會統一使用一個salt值(儲存在某個地方),而不是每個用戶都生成私有的salt值。
關於MD5
MD5本身是不可逆的散列加密算法。此前山東大學的一個教授給出的並不是真正意義上的逆向破解,只不過是找到縮短碰撞時間的方法。給定任意密文,立即還原原始報文,這種基於MD5的逆向解釋算法至少到目前為止,還沒有任何一個人或者組織公布出來。
所以,對於MD5,目前公認最有效的途徑只有一個,就是基於窮舉法的暴力破解。
這種方式取決於原始報文的長度、編碼等等,使用和原始密文同樣的MD5加密方式,對加密結果和原始密文進行比對,如果加密內容過長,編碼構成很復雜,基本可以判定為不可能。
關於AES
AES是一種基於私鑰的對稱加密算法。也就是說,AES,可以通過私鑰進行正向加密和逆向解密。這點上和MD5是有區別的。
AES的私鑰長度分為三種128、192和256三種。所以,對於AES密文的破解其實和常規的對稱算法一樣,窮舉私鑰。
理論上來說,AES的破解難度要小於MD5,畢竟私鑰的最大長度為256Byte。但是目前,似乎除了窮舉私鑰並沒有更好的方法來獲取私鑰。
如果想破解一個加密算法,建議先去研究一下需要破解這個加密算法。可以是數學模型/公式,或者直接去查各種語言對應的源碼。如果真的存在有牛人可以做出MD5的逆向算法;或者不需要私鑰就能獲取AES的原始報文;更或者直接通過密文獲取AES的私鑰。。那么,這樣的人可以去申請圖靈獎了。
總結一下:
上面已經分別分析了2種加密算法,給出個結論:
如果單純的是想破解密文,建議還是放棄吧。
如果是想模擬報文加密,可以考慮從程序里把AES的私鑰搞出來。很多程序的私鑰都是放在程序里的。
如果還有其它,不如考慮繞過加密部分,比如考慮一下在驗證的判斷上打打主意,甚至把加密部分去掉直接獲取原始報文。