java中MD5加密
阿新 • • 發佈:2020-07-20
MD5加密
MD5加密是一種常見的加密方式,我們經常用在儲存使用者密碼和關鍵資訊上。那麼它到底有什麼,又什麼好處呢,會被這麼廣泛的運用在應用開發中。
什麼是MD5
MD5加密全程是Message-Digest Algoorithm 5(資訊-摘要演算法),它對資訊進行摘要採集,再通過一定的位運算,最終獲取加密後的MD5字串。
例如我們要加密一篇文章,那麼我們會隨機從每段話或者每行中獲取一個字,把這些字統計出來後,再通過一定的運算獲得一個固定長度的MD5加密後資訊。因此,其很難被逆向破解。
MD5有哪些特點
- 針對不同長度待加密的資料、字串等等,其都可以返回一個固定長度的MD5加密字串。(通常32位的16進位制字串);
- 其加密過程幾乎不可逆,除非維護一個龐大的Key-Value資料庫來進行碰撞破解,否則幾乎無法解開。
- 運算簡便,且可實現方式多樣,通過一定的處理方式也可以避免碰撞演算法的破解。
- 對於一個固定的字串。數字等等,MD5加密後的字串是固定的,也就是說不管MD5加密多少次,都是同樣的結果。
java中實現MD5加密方式
1. 使用JDK自帶的API實現
加單實現如下
@Test void test1() { String pwd = "123456"; try { MessageDigest md = MessageDigest.getInstance("MD5");// 生成一個MD5加密計算摘要 md.update(pwd.getBytes());// 計算md5函式 /** * digest()最後確定返回md5 hash值,返回值為8位字串。 * 因為md5 hash值是16位的hex值,實際上就是8位的字元 * BigInteger函式則將8位的字串轉換成16位hex值,用字串來表示;得到字串形式的hash值 * 一個byte是八位二進位制,也就是2位十六進位制字元(2的8次方等於16的2次方) */ String hashedPwd = new BigInteger(1, md.digest()).toString(16);// 16是表示轉換為16進位制數 System.out.println(hashedPwd); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } }
結果:
e10adc3949ba59abbe56e057f20f883e
2. 使用Spring的DigestUtils工具類
@Test
void testMD5() {
String pwd = "123456";
// 基於spring框架中的DigestUtils工具類進行密碼加密
String hashedPwd1 = DigestUtils.md5DigestAsHex((pwd).getBytes());
System.out.println(hashedPwd1);
}
結果:
e10adc3949ba59abbe56e057f20f883e
改進- 加鹽
一般加密演算法固定,很容易破解,安全係數低,有很多網站可以直接破解密文。為了提高安全性,可以採取加鹽的方式。生成一組隨機串,儲存在資料庫中,然後混雜在原來的密碼中,再通過加密演算法加密,存進資料庫中
@Test
void testMD5() {
String pwd = "123456";
String salt = UUID.randomUUID().toString();
// 基於spring框架中的DigestUtils工具類進行密碼加密
String hashedPwd1 = DigestUtils.md5DigestAsHex((pwd + salt).getBytes());
System.out.println(hashedPwd1);
}
結果:
ce504625e463008803c1b875a0bd87a3
改進-加次數
多加密幾次也可增加破解的難度, 一般可用於交易碼等
@Test
void testMD5() {
String pwd = "123456";
String salt = UUID.randomUUID().toString();
// 基於spring框架中的DigestUtils工具類進行密碼加密
String hashedPwd1 = DigestUtils.md5DigestAsHex((pwd + salt).getBytes());
hashedPwd1 = DigestUtils.md5DigestAsHex((hashedPwd1 + salt).getBytes()); // +1次
hashedPwd1 = DigestUtils.md5DigestAsHex((hashedPwd1 + salt).getBytes()); // +2次
// ... 可使用迴圈等
System.out.println(hashedPwd1);
}
結果:
22cca33f84e7c72132dbff6fcfc60934
3. 使用Shiro的simpleHash進行加密
當然, 我們也可以加鹽加次數等
如下程式碼
@Test
void testShiroMD5() {
String pwd = "123456"; // 密碼
String salt = UUID.randomUUID().toString(); // 鹽
/**
* 引數1: 加密方式
* 引數2: 要加密的字串
* 引數3: 鹽
* 引數4: 加密次數
*/
SimpleHash sh = new SimpleHash("MD5", pwd, salt, 5); // 定義simpleHash物件
String hashedPwd = sh.toHex(); // 生成16進位制密文
System.out.println(hashedPwd); // 輸出
}
結果
b37e9129e9a6c1cecc8d34c60315fd8d