1. 程式人生 > 實用技巧 >java中MD5加密

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