MD5算法原理与常用实现
目錄
- 定義
- MD5特點(diǎn)
- 常見應(yīng)用場景
- 1、校驗(yàn)文件的完整性
- 2、存儲(chǔ)用戶密碼
- 原理
- 1、填補(bǔ)信息
- 2、拿到初始值
- 3、真正的計(jì)算
- MD5為什么不可逆
- java實(shí)現(xiàn)和使用
定義
MD全稱Message-Digest,即信息摘要,所以MD家族的算法也叫信息摘要算法
MD家族有MD2、MD3、MD4、MD5,一代比一代強(qiáng)。
所以MD5是MD算法家族中,目前最常用的一種加密算法。
任何信息,都可以通過MD5算法運(yùn)算生成一個(gè)16字節(jié)(128位)的散列值,但卻無法通過這16個(gè)字節(jié)的散列值獲得加密前的信息。
最終這16個(gè)散列值,通常用一個(gè)長度為32的十六進(jìn)制字符串來表示。
這就是MD5最重要的一個(gè)特性:加密不可逆。
MD5特點(diǎn)
加密不可逆,即無法通過密文得到原文。
不變性,即相同的原文,通過MD5算法得到的密文總是相同的。
散列性,即對原文作輕微的改動(dòng),都可導(dǎo)致最終的密文完全改變。
常見應(yīng)用場景
1、校驗(yàn)文件的完整性
如果張三給李四傳了一個(gè)文件,如何確認(rèn)這個(gè)文件傳給李四是完整的呢
張三傳文件前,先對文件做一個(gè)MD5加密,同時(shí)把MD5加密的密文傳給李四
李四收到文件,也對該文件做MD5加密,如果得到的密文和張三給的密文一樣,就說明文件是完整的。
2、存儲(chǔ)用戶密碼
用戶密碼,理論上也不能直接明文存儲(chǔ)在數(shù)據(jù)庫中,因?yàn)橐坏?shù)據(jù)庫被破解,用戶的密碼就全部丟失了
所以可以將用戶密碼做一個(gè)MD5加密,然后將密文存在數(shù)據(jù)庫中
用戶登錄的時(shí)候,可以將用戶的密碼進(jìn)行MD5加密,然后比對密文和數(shù)據(jù)庫中的密文是否一致,來判斷用戶前臺(tái)填的密碼是否正確。
這只是一個(gè)思路,一般不會(huì)這么簡單,一般生產(chǎn)環(huán)境會(huì)對用戶密碼加鹽加密等等的處理,用戶信息更加重要的,則需要更加復(fù)雜的計(jì)算邏輯。
原理
MD5的加密過程,整體來看,就是先定義四個(gè)值,然后用這四個(gè)值,對原文信息進(jìn)行計(jì)算,并得到新的四個(gè)值,然后再對原文進(jìn)行計(jì)算,再得到新的四個(gè)值,如此循環(huán)一定次數(shù),最終對最后的這四個(gè)值進(jìn)行簡單的字符串拼接,就得到了最終的密文。
主要就是下面這3步:
1、填補(bǔ)信息
用原文長度位數(shù)對512求余,如果結(jié)果不為448,就填充到448位。填充是第一位填1,后面填0。512-448=64,用這剩余的64位,記錄原文長度。
最終得到一個(gè)填補(bǔ)完的信息(總長=原文長度+512位)
2、拿到初始值
四個(gè)初始值,是MD5這個(gè)算法提前定義好的,分別是4個(gè)32位的值,總共剛好128位。
我們用ABCD命名:
A=0x01234567
B=0x89ABCDEF
C=0xFEDCBA98
D=0x76543210
3、真正的計(jì)算
計(jì)算分為多次循環(huán),每次循環(huán),都是用ABCD和原文在第一步填補(bǔ)完的信息,進(jìn)行計(jì)算,最終得到新的ABCD。最后將最后一次ABCD拼成字符串,就是最終的密文。
循環(huán)先分為主循環(huán),每個(gè)主循環(huán)中又套有子循環(huán)。
主循環(huán)次數(shù) = 原文長度/512。
子循環(huán)次數(shù) = 64次。
我們看看單次子循環(huán)都做了什么:
下面是單次子循環(huán)真正的計(jì)算邏輯(這段實(shí)現(xiàn)摘自網(wǎng)友):
圖中,A,B,C,D就是哈希值的四個(gè)分組。每一次循環(huán)都會(huì)讓舊的ABCD產(chǎn)生新的ABCD。一共進(jìn)行多少次循環(huán)呢?由處理后的原文長度決定。
假設(shè)處理后的原文長度是M
主循環(huán)次數(shù) = M / 512
每個(gè)主循環(huán)中包含 512 / 32 * 4 = 64 次 子循環(huán)。
上面這張圖所表達(dá)的就是單次子循環(huán)的流程。
下面對圖中其他元素一一解釋:
1.綠色F
圖中的綠色F,代表非線性函數(shù)。官方MD5所用到的函數(shù)有四種:
在主循環(huán)下面64次子循環(huán)中,F、G、H、I 交替使用,第一個(gè)16次使用F,第二個(gè)16次使用G,第三個(gè)16次使用H,第四個(gè)16次使用I。
2.紅色“田”字
很簡單,紅色的田字代表相加的意思。
3.Mi
Mi是第一步處理后的原文。在第一步中,處理后原文的長度是512的整數(shù)倍。把原文的每512位再分成16等份,命名為M0 ~ M15,每一等份長度32。在64次子循環(huán)中,每16次循環(huán),都會(huì)交替用到M1 ~ M16之一。
4.Ki
一個(gè)常量,在64次子循環(huán)中,每一次用到的常量都是不同的。
5.黃色的<<
FF(a,b,c,d,Mj,s,ti)表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)
<<<s表示循環(huán)左移s位
MD5為什么不可逆
MD5不可逆的原因,從原理上來看,
第一是他使用了散列函數(shù),即上面的FGHI函數(shù)。
第二是他在里面用了大量的移位操作,即<<<,這些是不可逆的
比如有10110011,我們左移三位,變成了10011000,高三位的101被頂了,低三位用0代替了,那此時(shí)就絕對不可能用10011000再逆向得到10110011了。
java實(shí)現(xiàn)和使用
public class MD5Util {public static void main(String[] args) throws IOException {System.out.println(encodeString("123"));}public static String encodeString(String plainText) throws UnsupportedEncodingException {return encodeBytes(plainText.getBytes("UTF-8"));}public static String encodeBytes(byte[] bytes) {try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(bytes);byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0) {i += 256;}if (i < 16) {buf.append("0");}buf.append(Integer.toHexString(i));}return buf.toString();} catch (Exception e) {e.printStackTrace();}return "";}}總結(jié)
以上是生活随笔為你收集整理的MD5算法原理与常用实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea插件开发(01)---最简单的h
- 下一篇: 关于iOS7里的JavaScriptCo