1. 程式人生 > >MD5資訊摘要演算法的簡單理解

MD5資訊摘要演算法的簡單理解

最近在做一個微專案的時候用到了MD5資訊摘要演算法,所以就簡單的瞭解了一下,我把我的瞭解寫下來,用作以後的學習。
一.MD5的簡單理解
        MD5的全稱是Message-Digest Algorithm 5(資訊摘要演算法),它面向的是32位的電腦,MD5演算法會獲得一個隨機的長度的資訊併產生一個128位的資訊摘要,(也就是說可以生成一個固定長度為128bit的二進位制串)。它是一個資訊摘要演算法,而摘要和加密是有區別的。
      1.1.摘要
        摘要是雜湊值,我們可以通過雜湊演算法比如MD5演算法得到雜湊值。它只是用於驗證資料完整性和唯一性的雜湊值,不管原始資料是什麼樣的,得到的雜湊值都是固定長度並且並不是直接由原始資料加密後的密文,只是根據原始資料生成了一個驗證身份的令牌。所以我們無法通過摘要解密得到原始資料。
      1.2.加密
        加密是加密演算法直接由明文加密成為密文,我們可以通過祕鑰和解密演算法將密文準確的還原成明文。
二.MD5演算法的特點

      2.1.壓縮性

        任意長度的資料計算出的MD5值得長度都是固定的。儲存和管理比較方便。

      2.2.易於計算

       資料計算出MD5值很容易,易於使用者的理解和使用 。

      2.3.細微性

        任意大小的資料,只要經過任何的改變,哪怕只修改某個位元組,所得到的MD5值都會有很大的區別,這個特點常被用於檔案下載的檢驗。

      2.4.不可逆性

        得到一個MD5值,無法反向計算出原資料

      2.5.弱相同性

        一個數據對應一個MD5值,一個MD5值可能對應多個原始資料。

三.MD5破解講解

      MD5破解的方式,因為MD5演算法是不可逆的,所以破解一般是"撞庫破解",也就是把大量的常用的語句經過MD5"加密"後放入資料庫,再把你輸入的語句經過MD5"加密"去和資料庫中的MD5值對比,然後返回原語句,這樣只能找出一些簡單的,常用的語句

四.MD5的加鹽

      單純的將資料MD5"加密"後,也有被對比,暴力破解的風險,所以我們需要加鹽,通俗來說就是在原資料中加入其他的資料,比如密碼(password),隨機數(random number),得到password的MD5值然後加上random number然後再次MD5後,得到這個MD5值,這就是個簡單的加鹽過程,這樣的話就算得到最後的這個MD5值得原資料,也得不到password。

五.MD5值的位數

      前面說了MD5後值為128bit的二進位制串,但二進位制都是01,會造成使用者的使用,理解不便,所以將128bit的二進位制串轉化為16進位制的串,所以就輸出的MD5值為32位。16位的MD5值是從32位的MD5值抽取出來的,32位MD5值去掉前後的八位,得到的值就是16位的MD5值。

六.MD5工具類(java)

public class MD5Util {

    private final static char hexDigits[] = {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    };
    //MD5加密的普通方式
    public static String getMD5(String key){
        try {
            byte[] btInput = key.getBytes();
            // 獲得MD5摘要演算法的 MessageDigest 物件
            MessageDigest mdInst = MessageDigest.getInstance("MD5");
            // 使用指定的位元組更新摘要
            mdInst.update(btInput);
            // 獲得密文
            byte[] md = mdInst.digest();
            // 把密文轉換成十六進位制的字串形式
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }
    //MD5加密的另一種方式
    public static String getOtherMD5(String key) {
        MessageDigest messageDigest = null;
        try {
            messageDigest = MessageDigest.getInstance("MD5");
            messageDigest.reset();
            messageDigest.update(key.getBytes("UTF-8"));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
        }
        byte[] byteArray = messageDigest.digest();
        StringBuffer md5StrBuff = new StringBuffer();
        for (int i = 0; i < byteArray.length; i++) {
            if (Integer.toHexString(0xFF & byteArray[i]).length() == 1)
                md5StrBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));
            else
                md5StrBuff.append(Integer.toHexString(0xFF & byteArray[i]));
        }
        return md5StrBuff.toString();
    }
    // 加密後解密,一次是加密,兩次解密
    public static String encrypt(String key) {
        char[] a = key.toCharArray();
        for (int i = 0; i < a.length; i++) {
            a[i] = (char) (a[i] ^ 't');
        }
        String k = new String(a);
        return k;
    }

}

或者使用commons-codecjar包,我這裡使用的是依賴

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
</dependency> 使用方式 String md5 = DigestUtils.md5Hex("123456");就可以了。若是哪裡有理解錯誤的或寫錯的地方,望各位讀者評論或者私信指正,不勝感激。