五分鐘搞懂摘要演算法

SoarYuan發表於2020-04-04

一.摘要演算法和摘要

1.概述

摘要演算法又稱雜湊演算法、雜湊演算法。摘要也稱雜湊值,表示輸入任意長度的資料,都會輸出固定長度的資料。通過摘要演算法(比如MDS和SHA-1)就可以得到該雜湊值。

2.特點

  • 長度固定,結果越長,認為摘要演算法越安全

  • 原始資料不同,生成的摘要一定不同

  • 單項不可逆

3、作用

摘要只驗證資料的完整性和唯一性,單項不可逆。 雜湊值長度都是固定的:MD5輸出128bit長度的二進位制串,SHA-1輸出160bit長度的二進位制串。128bit指二進位制位數是128。 (8bit=1byte128bit=16byte)。

4、誤區

摘要只是用於驗證資料完整性和唯一性的,不管原始資料是什麼樣的,得到的雜湊值都是固定長度的,也就是說雜湊值並不是原始資料加密後的密文,只是一個驗證身份的令牌,所以我們無法通過摘要還原出原始資料,即單向不可逆,所以說摘要演算法是加密演算法是不嚴謹的。

二.目前常用的摘要演算法

演算法 輸出長度
MD5 128bit
SHA-1 160bit
SHA-256 256bit

1.MD5

(1)MD5的用途

  • 驗證檔案完整性

  • 儲存使用者口令(比如密碼)

系統不用儲存使用者原始口令,而是儲存使用者原始口令的MD5,系統計算使用者輸入的原始口令的MD5並與資料儲存的MD5進行對比,如果相同,則說明口令正確,反之則說明口令錯誤。

(2)彩虹表

MD5雖然不可逆,也無法通過摘要還原出原始資料,但不代表一定安全。由於字串通過MD5計算的摘要是唯一的,那麼MD5字典隨著時間積累儲存越來越多的MD5記錄,通過窮舉這個字典就可以找到密碼。我們把這個字典稱為彩虹表。即採用各種Hash演算法生成的明文和密文的對照表。

(3)加鹽或者base64--防止彩虹表窮舉

抵禦彩虹表攻擊我們不能簡單的記錄原始口令的MD5值,需要讓原始資料變得夠長和夠複雜。可以通過base64編碼方法,對原始資料先進行base64編碼,再MD5,即md5(base64(password))。也可以通過加鹽的方法,對原始資料額外新增隨機數salt,再MD5,即md5(salt+password)。Java程式碼如下:

public static String md5(String string, String slat) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("MD5");
            byte[] bytes = md5.digest((string + slat).getBytes());
            String result = "";
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result += temp;
            }
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
    
複製程式碼

2.SHA-1

SHA-1演算法也是一種雜湊演算法,輸出160bit,它的同型別演算法有SHA-256和SHA-512,輸出的長度分別是256bit和512bit。SHA-1在Java中使用同MD5類似,Java程式碼如下:

public static String sha(String string) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        MessageDigest md5 = null;
        try {
            md5 = MessageDigest.getInstance("sha-1");
            byte[] bytes = md5.digest((string ).getBytes());
            String result = "";
            for (byte b : bytes) {
                String temp = Integer.toHexString(b & 0xff);
                if (temp.length() == 1) {
                    temp = "0" + temp;
                }
                result += temp;
            }
            return result;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }
    
複製程式碼

相關文章