java中MD5加密


MD5加密

MD5加密是一種常見的加密方式,我們經常用在保存用戶密碼和關鍵信息上。那么它到底有什么,又什么好處呢,會被這么廣泛的運用在應用開發中。

什么是MD5

MD5加密全程是Message-Digest Algoorithm 5(信息-摘要算法),它對信息進行摘要采集,再通過一定的位運算,最終獲取加密后的MD5字符串。
  例如我們要加密一篇文章,那么我們會隨機從每段話或者每行中獲取一個字,把這些字統計出來后,再通過一定的運算獲得一個固定長度的MD5加密后信息。因此,其很難被逆向破解。

MD5有哪些特點

  1. 針對不同長度待加密的數據、字符串等等,其都可以返回一個固定長度的MD5加密字符串。(通常32位的16進制字符串);
  2. 其加密過程幾乎不可逆,除非維護一個龐大的Key-Value數據庫來進行碰撞破解,否則幾乎無法解開。
  3. 運算簡便,且可實現方式多樣,通過一定的處理方式也可以避免碰撞算法的破解。
  4. 對於一個固定的字符串。數字等等,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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM