1. 程式人生 > >轉:MD5(Message-Digest Algorithm 一種哈希算法)

轉:MD5(Message-Digest Algorithm 一種哈希算法)

base64算法 會有 運算 rac object urn tst 密文 null

什麽是MD5算法

  MD5訊息摘要演算法(英語:MD5 Message-Digest Algorithm),一種被廣泛使用的密碼雜湊函數,可以產生出一個128位元(16位元組)的散列值(hash value),用於確保信息傳輸完整一致。

  實質上,MD5 只是一種哈希算法

  哈希算法,即 hash,又叫散列算法,是一類把任意數據轉換為定長(或限制長度)數據的算法統稱。例如我叫張三,你叫李四,那麽「人 -> 人名」的算法就叫屬於一種哈希算法。哈希算法通常用於制作數字指紋,數字指紋的意思就是「你看到這個東西就像看到原數據一樣」,例如我們在一些網站下載大文件的時候,網站提供給我們驗證文件完整性的 MD5 或者 SHA1 碼,就是原文件的哈希值。哈希算法有很多種,MD5 是其中的一種,這就是 MD5。所以,優秀的哈希算法通常需要具有低碰撞概率(即不同數據的哈希值通常也不一樣)。

  Java中的Object.hashCode()方法就是一個摘要算法,它可以輸入任意數據,它的輸出是一個int類型,即4個字節的固定長度數據,同時,相同的輸入會得到相同的輸出,這也是重寫equals方法必須重寫hashCode方法的原因。

MD5屬不屬於加密算法

  認為不屬於的人是因為他們覺得不能從密文(散列值)反過來得到原文,即沒有解密算法,所以這部分人認為MD5只能屬於算法,不能稱為加密算法;
  認為屬於的人是因為他們覺得經過MD5處理後看不到原文,即已經將原文加密,所以認為MD5屬於加密算法;我個人支持前者,正如認為BASE64算法只能算編碼一樣。

  加密,指的是對數據進行轉換以後,數據變成了另一種格式,並且除了拿到解密方法的人,沒人能把數據轉換回來。因此,加密通常用於網絡通信。因為網絡上的通信數據,任何人都有可能會拿到,把數據加密後再傳送,送達以後由對方解密後再查看,就可以防止網絡上的偷窺。

MD5算法是否可逆?

  MD5不可逆的原因是其是一種散列函數,使用的是hash算法,在計算過程中原文的部分信息是丟失了的。即從明文到密文的不可逆映射,只有加密過程沒有解密過程,哈希函數可以將任意長度的輸入經過變化後得到固定長度的輸出,這個固定長度的輸出稱為原消息的散列或消息映射。 理想的哈希函數可以針對不同的輸入得到不同的輸出,如果存在兩個不同的消息得到了相同的哈希值,那我們稱這是一個碰撞)  

  不過有個地方值得指出的是,一個MD5理論上的確是可能對應無數多個原文的,因為MD5是有限多個的而原文可以是無數多個。比如主流使用的MD5將任意長度的“字節串映射為一個128bit的大整數。也就是一共有2^128種可能,大概是3.4*10^38,這個數字是有限多個的,而但是世界上可以被用來加密的原文則會有無數的可能性。

  不過需要註意的一點是,盡量這是一個理論上的有限對無限,不過問題是這個無限在現實生活中並不完全成立,因為一方面現實中原文的長度往往是有限的(以常用的密碼為例,一般人都在20位以內),另一方面目前想要發現兩段原文對應同一個MD5(專業的說這叫雜湊沖撞)值非常困難,因此某種意義上來說,在一定範圍內想構建MD5值與原文的一一對應關系是完全有可能的。所以對於MD5目前最有效的攻擊方式就是彩虹表。

MD5用途 

1.防止被篡改:
  1)比如發送一個電子文檔,發送前,我先得到MD5的輸出結果a。然後在對方收到電子文檔後,對方也得到一個MD5的輸出結果b。如果a與b一樣就代表中途未被篡改。
  2)比如我提供文件下載,為了防止不法分子在安裝程序中添加木馬,我可以在網站上公布由安裝文件得到的MD5輸出結果。
  3)SVN在檢測文件是否在CheckOut後被修改過,也是用到了MD5.

2.防止直接看到明文:
  現在很多網站在數據庫存儲用戶的密碼的時候都是存儲用戶密碼的MD5值。這樣就算不法分子得到數據庫的用戶密碼的MD5值,也無法知道用戶的密碼。(比如在UNIX系統中用戶的密碼就是以MD5(或其它類似的算法)經加密後存儲在文件系統中。當用戶登錄的時候,系統把用戶輸入的密碼計算成MD5值,然後再去和保存在文件系統中的MD5值進行比較,進而確定輸入的密碼是否正確。通過這樣的步驟,系統在並不知道用戶密碼的明碼的情況下就可以確定用戶登錄系統的合法性。這不但可以避免用戶的密碼被具有系統管理員權限的用戶知道,而且還在一定程度上增加了密碼被破解的難度。)

3.防止抵賴(數字簽名):
  這需要一個第三方認證機構。例如A寫了一個文件,認證機構對此文件用MD5算法產生摘要信息並做好記錄。若以後A說這文件不是他寫的,權威機構只需對此文件重新產生摘要信息,然後跟記錄在冊的摘要信息進行比對,相同的話,就證明是A寫的了。這就是所謂的“數字簽名”。

MD5安全性

  普遍認為MD5是很安全,因為暴力破解的時間是一般人無法接受的。實際上如果把用戶的密碼MD5處理後再存儲到數據庫,其實是很不安全的。因為用戶的密碼是比較短的,而且很多用戶的密碼都使用生日,手機號碼,身份證號碼,電話號碼等等。或者使用常用的一些吉利的數字,或者某個英文單詞。如果我把常用的密碼先MD5處理,把數據存儲起來,然後再跟你的MD5結果匹配,這時我就有可能得到明文。比如某些MD5破解網站,所以現在大多數網站密碼的策略是強制要求用戶使用數字大小寫字母的組合的方式提高用戶密碼的安全度。

目前常用的摘要算法:

技術分享圖片

java中對MD5算法的使用:

public class SummaryAlgorithm {

	public static void main(String[] args) throws UnsupportedEncodingException {
		String str = "MD5摘要算法";
		byte[] testByte = toMD5(str.getBytes());
		System.out.println(String.format("%32x", new BigInteger(1, testByte)));
		
		String salt = "random";
        byte[] digest = toMD5((str + salt).getBytes("UTF-8"));
        // %x表示返回的是16進制,而32表示16個字節
        System.out.println(String.format("%32x", new BigInteger(1, digest)));
	}
	
	public static byte[] toMD5(byte[] input) {
		MessageDigest md = null;
		try {
			md = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		md.update(input);
		return md.digest();
	}
}

 MD5算法實現:

  輸入:不定長度信息(要加密的信息)

  輸出:固定長度128-bits。由四個32位分組組成,將這四個32位分組級聯後將生成一個128位散列值。

  基本方式為:求余、取余、調整長度、與鏈接變量進行循環運算。得出結果。

  具體過程請查看MD5算法。算法的的設計目的就是防碰撞,不可逆。

轉:MD5(Message-Digest Algorithm 一種哈希算法)