Java 加解密技術系列之 SHA

來源:互聯網
上載者:User

標籤:sans   sse   sha1   sys   its   建構函式   target   二進位   bytes   

序 上一篇文章中介紹了基本的單向密碼編譯演算法 — — MD5,也大致的說了說它實現的原理。這篇文章繼續之前提到的單向加密,主要講的是 SHA,同 MD5 一樣,SHA 同樣也是一個系列,它包括 SHA-1,SHA-224,SHA-256,SHA-384,和 SHA-512 等幾種演算法。其中,SHA-1,SHA-224 和 SHA-256 適用於長度不超過 2^64 二進位位的訊息。SHA-384 和 SHA-512 適用於長度不超過 2^128 二進位位的訊息。  背景 開始本文之前,簡單的說一下背景。乍一說 SHA 你可能不知道,但說到散列和散列演算法,你一定會知道,也就是平常所指的 Hash。那麼,先瞭解一下什麼是散列。散列,是資訊的提煉,通常其長度要比資訊小得多,且為一個固定長度。加密性強的散列一定是無法復原的,這就意味著通過散列結果,無法推出任何部分的原始資訊。說的很明確,散列的結果是無法復原的,根據散列結果,無法推出原始資訊。  本文 瞭解了背景之後,我們就開始介紹 SHA 了。 SHA,全稱為“Secure Hash Algorithm”,中文名“安全雜湊演算法”,主要適用於數位簽章標準 (DSS)(Digital Signature Standard DSS)裡面定義的數位簽章演算法(Digital Signature Algorithm DSA)。對於長度小於 2^64 位元的訊息,SHA1 會產生一個 160 位的訊息摘要。 該演算法的思想是接收一段明文,然後以一種無法復原的方式將它轉換成一段(通常更小)密文,也可以簡單的理解為取一串輸入碼(稱為預映射或資訊),並把它們轉化為長度較短、位元固定的輸出序列即散列值的過程。 上邊也提到了,SHA 規定了很多種演算法,包括了 SHA-1,SHA-224,SHA-256,等很多種。這裡我以 SHA-1 為例,講一下 SHA-1 是如何工作的。 SHA-1 有兩個特點:
  • 不可以從訊息摘要中複原資訊
  • 兩個不同的訊息,不會產生同樣的訊息摘要
 SHA-1 是一種資料加密演算法,主要是接收一段明文,然後以一種無法復原的方式將它轉換成一段密文,也可以簡單的理解為取一串輸入碼,並把它們轉化為長度較短、位元固定的輸出序列即散列值的過程。 單向散列函數的安全性在於其產生散列值的操作過程具有較強的單向性。如果在輸入序列中嵌入密碼,那麼任何人在不知道密碼的情況下都不能產生正確的散列值,從而保證了其安全性。SHA 將輸入資料流按照每塊 512 位(64 個位元組)進行分塊,併產生 20 個位元組的被稱為資訊認證代碼或資訊摘要的輸出。 該演算法輸入報文的長度不限,產生的輸出是一個 160 位的報文摘要。輸入是按 512 位的分組進行處理的。SHA-1 是無法復原的、防衝突,並具有良好的雪崩效應。 通過散列演算法可實現數位簽章實現,數位簽章的原理是將要傳送的明文通過一種函數運算(Hash)轉換成報文摘要(不同的明文對應不同的報文摘要),報文摘要加密後與明文一起傳送給接受方,接受方將接受的明文產生新的報文摘要與發送方的發來報文摘要解密比較,比較結果一致表示明文未被改動,如果不一致表示明文已被篡改。  SHA-1 與 MD5 的比較 因為二者均由 MD4 匯出,SHA-1 和 MD5 彼此很相似。相應的,他們的強度和其他特性也是相似,但還有以下幾點不同: 
  • 對強行攻擊的安全性
 最顯著和最重要的區別是 SHA-1 摘要比 MD5 摘要長 32 位。使用強行技術,產生任何一個報文使其摘要等於給定報摘要的難度對 MD5 是 2^128 數量級的操作,而對 SHA-1 則是 2^160 數量級的操作。這樣,SHA-1 對強行攻擊有更大的強度。 
  • 對密碼分析的安全性
 由於 MD5 的設計,易受密碼分析的攻擊,SHA-1 顯得不易受這樣的攻擊。 
  • 速度
 在相同的硬體上,SHA-1 的運行速度比 MD5 慢。  代碼實現  [java] view plain copy  
  1. <span style="font-family:Comic Sans MS;font-size:12px;">package com.sica.sha;  
  2.   
  3. import com.google.common.base.Strings;  
  4.   
  5. import java.security.MessageDigest;  
  6.   
  7. /** 
  8.  * Created by xiang.li on 2015/2/11. 
  9.  */  
  10. public class SHA {  
  11.     /** 
  12.      * 定義加密方式 
  13.      */  
  14.     private final static String KEY_SHA = "SHA";  
  15.     private final static String KEY_SHA1 = "SHA-1";  
  16.     /** 
  17.      * 全域數組 
  18.      */  
  19.     private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",  
  20.             "6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };  
  21.   
  22.     /** 
  23.      * 建構函式 
  24.      */  
  25.     public SHA() {  
  26.   
  27.     }  
  28.   
  29.     /** 
  30.      * SHA 加密 
  31.      * @param data 需要加密的位元組數組 
  32.      * @return 加密之後的位元組數組 
  33.      * @throws Exception 
  34.      */  
  35.     public static byte[] encryptSHA(byte[] data) throws Exception {  
  36.         // 建立具有指定演算法名稱的資訊摘要  
  37. //        MessageDigest sha = MessageDigest.getInstance(KEY_SHA);  
  38.         MessageDigest sha = MessageDigest.getInstance(KEY_SHA1);  
  39.         // 使用指定的位元組數組對摘要進行最後更新  
  40.         sha.update(data);  
  41.         // 完成摘要計算並返回  
  42.         return sha.digest();  
  43.     }  
  44.   
  45.     /** 
  46.      * SHA 加密 
  47.      * @param data 需要加密的字串 
  48.      * @return 加密之後的字串 
  49.      * @throws Exception 
  50.      */  
  51.     public static String encryptSHA(String data) throws Exception {  
  52.         // 驗證傳入的字串  
  53.         if (Strings.isNullOrEmpty(data)) {  
  54.             return "";  
  55.         }  
  56.         // 建立具有指定演算法名稱的資訊摘要  
  57.         MessageDigest sha = MessageDigest.getInstance(KEY_SHA);  
  58.         // 使用指定的位元組數組對摘要進行最後更新  
  59.         sha.update(data.getBytes());  
  60.         // 完成摘要計算  
  61.         byte[] bytes = sha.digest();  
  62.         // 將得到的位元組數組變成字串返回  
  63.         return byteArrayToHexString(bytes);  
  64.     }  
  65.   
  66.     /** 
  67.      * 將一個位元組轉化成十六進位形式的字串 
  68.      * @param b 位元組數組 
  69.      * @return 字串 
  70.      */  
  71.     private static String byteToHexString(byte b) {  
  72.         int ret = b;  
  73.         //System.out.println("ret = " + ret);  
  74.         if (ret < 0) {  
  75.             ret += 256;  
  76.         }  
  77.         int m = ret / 16;  
  78.         int n = ret % 16;  
  79.         return hexDigits[m] + hexDigits[n];  
  80.     }  
  81.   
  82.     /** 
  83.      * 轉換位元組數組為十六進位字串 
  84.      * @param bytes 位元組數組 
  85.      * @return 十六進位字串 
  86.      */  
  87.     private static String byteArrayToHexString(byte[] bytes) {  
  88.         StringBuffer sb = new StringBuffer();  
  89.         for (int i = 0; i < bytes.length; i++) {  
  90.             sb.append(byteToHexString(bytes[i]));  
  91.         }  
  92.         return sb.toString();  
  93.     }  
  94.   
  95.     /** 
  96.      * 測試方法 
  97.      * @param args 
  98.      */  
  99.     public static void main(String[] args) throws Exception {  
  100.         String key = "123";  
  101.         System.out.println(encryptSHA(key));  
  102.     }  
  103. }</span>  
  結束語 看到這,我想 SHA-1 的簡單原理你應該是瞭解了,而且,對於應用來說也並不難,可以參考上述的 Java 代碼。回過頭來在想想 MD5,通過上面的文章,你就能知道,其實,SHA-1 與 MD5 是同出一轍的,只是他們各自的實現方式不同,SHA-1 在位運算元量級上也要比 MD5 更加的複雜,因此,對於安全的考慮,SHA-1 相對來說還是很可靠的。 至於什麼時候會用到它,那麼就要考慮 SHA-1 的特點了。很明確的,無法復原性,以及唯一性。那麼,我想,適用於 MD5 的加密的,也同樣適用於 SHA-1。而且,在安全性上來說,SHA-1 更勝於 MD5,如果是對速度有嚴格要求的話,那麼,還是優先考慮 MD5 吧。

Java 加解密技術系列之 SHA

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.