摘要算法是 一種能產生特殊輸出格式的算法,這種算法的特色是:不管用戶輸入什麼長度的原始數據,通過計算後輸出的密文都是固定長度的,這種算法的原理是根據必定的運算規則對原數據進行某種形式的提取,這種提取就是摘要,被摘要的數據內容與原數據有密切聯繫,只要原數據稍有改變,輸出的「摘要」便徹底不一樣,所以,基於這種原理的算法便能對數據完整性提供較爲健全的保障。可是,因爲輸出的密文是提取原數據通過處理的定長值,因此它已經不能還原爲原數據,即消息摘要算法是不可逆的,理論上沒法經過反向運算取得原數據內容,所以它一般只能被用來作數據完整性驗證。java
現在經常使用的「消息摘要」算法經歷了多年驗證發展而保留下來的算法已經很少,這其中包括MD二、MD四、MD五、SHA、SHA-1/256/383/512等。git
經常使用的摘要算法主要有MD5和SHA1。MD5的輸出結果爲16字節,sha1的輸出結果爲20字節。算法
固定長度安全
只要元數據改變,輸出摘要徹底不一樣函數
只有摘要提取,沒有所謂的解碼,即不可逆this
java.security.MessageDigest類用於爲應用程序提供信息摘要算法的功能,如 MD5 或 SHA 算法。簡單點說就是用於生成散列碼。信息摘要是安全的單向哈希函數,它接收任意大小的數據,輸出固定長度的哈希值。spa
MessageDigest 經過其getInstance系列靜態函數來進行實例化和初始化。MessageDigest 對象經過使用 update
方法處理數據。任什麼時候候均可以調用 reset
方法重置摘要。一旦全部須要更新的數據都已經被更新了,應該調用 digest
方法之一完成哈希計算並返回結果。設計
將一個字符串進行摘要,而後輸出16進制字符串code
public class MD5Util { public final static String MD5(String s) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; try { byte[] btInput = s.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) { e.printStackTrace(); return null; } } public static void main(String[] args) { System.out.println(MD5Util.MD5("20121221")); System.out.println(MD5Util.MD5("Digest Str......")); } }
SHA-1算法:對象
1995年,發佈了SHA-1算法,一般咱們把SHA-1算法簡稱爲SHA算法。SHA-1算法在許多安全協定中廣 爲使用,包括TLS/SSL、 PGP、SSH、S/MIME和IPsec,曾被視爲是MD5算法的後繼者。SHA-0和SHA-1算法可對最大長度爲264的字節信息作摘要處理,獲得 一個160的摘要信息,其設計原理類似於MD4和MD5算法。若是將獲得160位的摘要信息換算成十六進制,能夠獲得一個40位的字符串。
同樣的代碼結構,調用Digest方法的時候把參數改成"SHA",所以根據上述代碼作了如下修改,輸出依然是16進制字符串
import java.security.MessageDigest; public class DigestUtil { private enum DigestType{ MD5("MD5") ,SHA("SHA"); private String digestDesc; private DigestType(String digestDesc){ this.digestDesc = digestDesc; } public String getDigestDesc() { return digestDesc; } } private final static String digest(String sourceStr,DigestType type) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; try { byte[] btInput = sourceStr.getBytes(); // 得到MD5摘要算法的 MessageDigest 對象 MessageDigest mdInst = MessageDigest.getInstance(type.digestDesc); // 使用指定的字節更新摘要 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) { e.printStackTrace(); return null; } } public final static String MD5(String s) { return digest(s, DigestType.MD5); } public final static String SHA(String s) { return digest(s, DigestType.SHA); } public static void main(String[] args) { String sourceStr1 = "20121221"; String sourceStr2 = "Digest Str......"; System.out.println(DigestUtil.MD5(sourceStr1)); System.out.println(DigestUtil.MD5(sourceStr2)); System.out.println(DigestUtil.SHA(sourceStr1)); System.out.println(DigestUtil.SHA(sourceStr2)); } }
SHA-2算法:
SHA算法家族除了其表明SHA-1算法之外,還有SHA-22四、SHA-25六、SHA-384和SHA-512四種SHA算法的變體,以其摘 要信息字節長度不一樣而命名,一般將這組算法並稱爲SHA-2算法。摘要信息字節長度的差別是SHA-2和SHA-1算法的最大差別。
繼續修改代碼
import java.security.MessageDigest; public class DigestUtil { private enum DigestType{ MD5("MD5") ,SHA("SHA") ,SHA256("SHA-256") ,SHA512("SHA-512"); private String digestDesc; private DigestType(String digestDesc){ this.digestDesc = digestDesc; } public String getDigestDesc() { return digestDesc; } } private final static String digest(String sourceStr,DigestType type) { char hexDigits[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; try { byte[] btInput = sourceStr.getBytes(); // 得到MD5摘要算法的 MessageDigest 對象 MessageDigest mdInst = MessageDigest.getInstance(type.digestDesc); // 使用指定的字節更新摘要 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) { e.printStackTrace(); return null; } } public final static String MD5(String s) { return digest(s, DigestType.MD5); } public final static String SHA(String s) { return digest(s, DigestType.SHA); } public final static String SHA256(String s){ return digest(s, DigestType.SHA256); } public final static String SHA512(String s){ return digest(s, DigestType.SHA512); } public static void main(String[] args) { String sourceStr1 = "20121221"; String sourceStr2 = "Digest Str......"; // System.out.println(DigestUtil.MD5(sourceStr1)); // System.out.println(DigestUtil.MD5(sourceStr2)); // // System.out.println(DigestUtil.SHA(sourceStr1)); // System.out.println(DigestUtil.SHA(sourceStr2)); System.out.println(DigestUtil.SHA256(sourceStr1)); System.out.println(DigestUtil.SHA256(sourceStr2)); System.out.println(DigestUtil.SHA512(sourceStr1)); System.out.println(DigestUtil.SHA512(sourceStr2)); } }