1. 程式人生 > >BASE64、MD5、SHA、HMAC幾種加密演算法(轉)

BASE64、MD5、SHA、HMAC幾種加密演算法(轉)

本篇內容簡要介紹BASE64MD5SHAHMAC幾種加密演算法。
    BASE64編碼演算法不算是真正的加密演算法。
    MD5SHAHMAC這三種加密演算法,可謂是非可逆加密,就是不可解密的加密方法我們稱之為單向加密演算法。我們通常只把他們作為加密的基礎。單純的以上三種的加密並不可靠。

BASE64
按照RFC2045的定義,Base64被定義為:Base64內容傳送編碼被設計用來把任意序列的8位位元組描述為一種不易被人類直接識別的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)
常見於郵件、http加密,擷取http資訊,你就會發現登入操作的使用者名稱、密碼欄位通過BASE64加密的。


通過java程式碼實現如下:

Java程式碼  收藏程式碼

  1. /** 
  2.  * BASE64解密 
  3.  * @param key 
  4.  * @return 
  5.  * @throws Exception 
  6.  */  
  7. public static byte[] decryptBASE64(String key) throws Exception {  
  8.     return (new BASE64Decoder()).decodeBuffer(key);  
  9. }  
  10.   
  11. /** 
  12.  * BASE64加密 
  13.  * @param key 
  14.  * @return 
  15.  * @throws Exception 
  16.  */  
  17. public static String encryptBASE64(byte[] key) throws Exception {  
  18.     return (new BASE64Encoder()).encodeBuffer(key);  
  19. }  


主要就是BASE64Encoder、BASE64Decoder兩個類,我們只需要知道使用對應的方法即可。另,BASE加密後產生的位元組位數是8的倍數,如果不夠位數以=符號填充。

MD5
MD5 -- message-digest algorithm 5 (資訊-摘要演算法)縮寫,廣泛用於加密和解密技術,常用於檔案校驗。校驗?不管檔案多大,經過MD5後都能生成唯一的MD5值。好比現在的ISO校驗,都是MD5校驗。怎麼用?當然是把ISO經過MD5後產生MD5的值。一般下載linux-ISO的朋友都見過下載連結旁邊放著MD5的串。就是用來驗證檔案是否一致的。


通過java程式碼實現如下:

Java程式碼  收藏程式碼

  1. /** 
  2.  * MD5加密 
  3.  * @param data 
  4.  * @return 
  5.  * @throws Exception 
  6.  */  
  7. public static byte[] encryptMD5(byte[] data) throws Exception {  
  8.     MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);  
  9.     md5.update(data);  
  10.     return md5.digest();   
  11. }  

通常我們不直接使用上述MD5加密。通常將MD5產生的位元組陣列交給BASE64再加密一把,得到相應的字串。

SHA
SHA(Secure Hash Algorithm,安全雜湊演算法),數字簽名等密碼學應用中重要的工具,被廣泛地應用於電子商務等資訊保安領域。雖然,SHA與MD5通過碰撞法都被破解了, 但是SHA仍然是公認的安全加密演算法,較之MD5更為安全。
通過java程式碼實現如下:

Java程式碼  收藏程式碼

  1.     /** 
  2.      * SHA加密 
  3.      *  
  4.      * @param data 
  5.      * @return 
  6.      * @throws Exception 
  7.      */  
  8.     public static byte[] encryptSHA(byte[] data) throws Exception {  
  9.   
  10.         MessageDigest sha = MessageDigest.getInstance(KEY_SHA);  
  11.         sha.update(data);  
  12.         return sha.digest();  
  13.   
  14.     }  
  15. }  



HMAC
HMAC(Hash Message Authentication Code,雜湊訊息鑑別碼,基於金鑰的Hash演算法的認證協議。訊息鑑別碼實現鑑別的原理是,用公開函式和金鑰產生一個固定長度的值作為認證標識,用這個標識鑑別訊息的完整性。使用一個金鑰生成一個固定大小的小資料塊,即MAC,並將其加入到訊息中,然後傳輸。接收方利用與傳送方共享的金鑰進行鑑別認證等。



通過java程式碼實現如下:

Java程式碼  收藏程式碼

  1. /** 
  2.  * 初始化HMAC金鑰 
  3.  *  
  4.  * @return 
  5.  * @throws Exception 
  6.  */  
  7. public static String initMacKey() throws Exception {  
  8.     KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);  
  9.     SecretKey secretKey = keyGenerator.generateKey();  
  10.     return encryptBASE64(secretKey.getEncoded());  
  11. }  
  12.   
  13. /** 
  14.  * HMAC加密 
  15.  *  
  16.  * @param data 
  17.  * @param key 
  18.  * @return 
  19.  * @throws Exception 
  20.  */  
  21. public static byte[] encryptHMAC(byte[] data, String key) throws Exception {  
  22.   
  23.     SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);  
  24.     Mac mac = Mac.getInstance(secretKey.getAlgorithm());  
  25.     mac.init(secretKey);  
  26.     return mac.doFinal(data);  
  27.   
  28. }  



給出一個完整類,如下:

Java程式碼  收藏程式碼

  1. import java.security.MessageDigest;  
  2. import javax.crypto.KeyGenerator;  
  3. import javax.crypto.Mac;  
  4. import javax.crypto.SecretKey;  
  5. import sun.misc.BASE64Decoder;  
  6. import sun.misc.BASE64Encoder;  
  7.   
  8. /** 
  9.  * 基礎加密元件 
  10.  * @author
  11.  * @version 1.0 
  12.  * @since 1.0 
  13.  */  
  14. public abstract class Coder {  
  15.     public static final String KEY_SHA = "SHA";  
  16.     public static final String KEY_MD5 = "MD5";  
  17.     /** 
  18.      * MAC演算法可選以下多種演算法 
  19.      * <pre> 
  20.      * HmacMD5  
  21.      * HmacSHA1  
  22.      * HmacSHA256  
  23.      * HmacSHA384  
  24.      * HmacSHA512 
  25.      * </pre> 
  26.      */  
  27.     public static final String KEY_MAC = "HmacMD5";  
  28.     /** 
  29.      * BASE64解密 
  30.      * @param key 
  31.      * @return 
  32.      * @throws Exception 
  33.      */  
  34.     public static byte[] decryptBASE64(String key) throws Exception {  
  35.         return (new BASE64Decoder()).decodeBuffer(key);  
  36.     }  
  37.   
  38.     /** 
  39.      * BASE64加密 
  40.      * @param key 
  41.      * @return 
  42.      * @throws Exception 
  43.      */  
  44.     public static String encryptBASE64(byte[] key) throws Exception {  
  45.         return (new BASE64Encoder()).encodeBuffer(key);  
  46.     }  
  47.   
  48.     /** 
  49.      * MD5加密 
  50.      * @param data 
  51.      * @return 
  52.      * @throws Exception 
  53.      */  
  54.     public static byte[] encryptMD5(byte[] data) throws Exception {  
  55.         MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);  
  56.         md5.update(data);  
  57.         return md5.digest();  
  58.     }  
  59.   
  60.     /** 
  61.      * SHA加密 
  62.      * @param data 
  63.      * @return 
  64.      * @throws Exception 
  65.      */  
  66.     public static byte[] encryptSHA(byte[] data) throws Exception {  
  67.         MessageDigest sha = MessageDigest.getInstance(KEY_SHA);  
  68.         sha.update(data);  
  69.         return sha.digest();  
  70.     }  
  71.   
  72.     /** 
  73.      * 初始化HMAC金鑰 
  74.      * @return 
  75.      * @throws Exception 
  76.      */  
  77.     public static String initMacKey() throws Exception {  
  78.         KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);  
  79.         SecretKey secretKey = keyGenerator.generateKey();  
  80.         return encryptBASE64(secretKey.getEncoded());  
  81.     }  
  82.   
  83.     /** 
  84.      * HMAC加密 
  85.      * @param data 
  86.      * @param key 
  87.      * @return 
  88.      * @throws Exception 
  89.      */  
  90.     public static byte[] encryptHMAC(byte[] data, String key) throws Exception {  
  91.   
  92.         SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);  
  93.         Mac mac = Mac.getInstance(secretKey.getAlgorithm());  
  94.         mac.init(secretKey);  
  95.   
  96.         return mac.doFinal(data);  
  97.   
  98.     }  
  99. }  



再給出一個測試類:

Java程式碼  收藏程式碼

  1. import static org.junit.Assert.*;  
  2.   
  3. import org.junit.Test;  
  4.   
  5. /** 
  6.  *  
  7.  * @author
  8.  * @version 1.0 
  9.  * @since 1.0 
  10.  */  
  11. public class CoderTest {  
  12.   
  13.     @Test  
  14.     public void test() throws Exception {  
  15.         String inputStr = "簡單加密";  
  16.         System.err.println("原文:/n" + inputStr);  
  17.   
  18.         byte[] inputData = inputStr.getBytes();  
  19.         String code = Coder.encryptBASE64(inputData);  
  20.   
  21.         System.err.println("BASE64加密後:/n" + code);  
  22.   
  23.         byte[] output = Coder.decryptBASE64(code);  
  24.   
  25.         String outputStr = new String(output);  
  26.   
  27.         System.err.println("BASE64解密後:/n" + outputStr);  
  28.   
  29.         // 驗證BASE64加密解密一致性  
  30.         assertEquals(inputStr, outputStr);  
  31.   
  32.         // 驗證MD5對於同一內容加密是否一致  
  33.         assertArrayEquals(Coder.encryptMD5(inputData), Coder  
  34.                 .encryptMD5(inputData));  
  35.   
  36.         // 驗證SHA對於同一內容加密是否一致  
  37.         assertArrayEquals(Coder.encryptSHA(inputData), Coder  
  38.                 .encryptSHA(inputData));  
  39.   
  40.         String key = Coder.initMacKey();  
  41.         System.err.println("Mac金鑰:/n" + key);  
  42.   
  43.         // 驗證HMAC對於同一內容,同一金鑰加密是否一致  
  44.         assertArrayEquals(Coder.encryptHMAC(inputData, key), Coder.encryptHMAC(  
  45.                 inputData, key));  
  46.   
  47.         BigInteger md5 = new BigInteger(Coder.encryptMD5(inputData));  
  48.         System.err.println("MD5:/n" + md5.toString(16));  
  49.   
  50.         BigInteger sha = new BigInteger(Coder.encryptSHA(inputData));  
  51.         System.err.println("SHA:/n" + sha.toString(32));  
  52.   
  53.         BigInteger mac = new BigInteger(Coder.encryptHMAC(inputData, inputStr));  
  54.         System.err.println("HMAC:/n" + mac.toString(16));  
  55.     }  
  56. }  



控制檯輸出:

Console程式碼  收藏程式碼

  1. 原文:  
  2. 簡單加密  
  3. BASE64加密後:  
  4. 566A5Y2V5Yqg5a+G  
  5.   
  6. BASE64解密後:  
  7. 簡單加密  
  8. Mac金鑰:  
  9. uGxdHC+6ylRDaik++leFtGwiMbuYUJ6mqHWyhSgF4trVkVBBSQvY/a22xU8XT1RUemdCWW155Bke  
  10. pBIpkd7QHg==  
  11.   
  12. MD5:  
  13. -550b4d90349ad4629462113e7934de56  
  14. SHA:  
  15. 91k9vo7p400cjkgfhjh0ia9qthsjagfn  
  16. HMAC:  
  17. 2287d192387e95694bdbba2fa941009a  



    BASE64的加密解密是雙向的,可以求反解。
    MD5、SHA以及HMAC是單向加密,任何資料加密後只會產生唯一的一個加密串,通常用來校驗資料在傳輸過程中是否被修改。其中HMAC演算法有一個金鑰,增強了資料傳輸過程中的安全性,強化了演算法外的不可控因素。單向加密的用途主要是為了校驗資料在傳輸過程中是否被修改。

--------------------- 本文來自 winter13292 的CSDN 部落格 ,全文地址請點選:https://blog.csdn.net/winter13292/article/details/6528554?utm_source=copy