1. 程式人生 > >Java中常用的加密方式

Java中常用的加密方式

加密,是以某種特殊的演算法改變原有的資訊資料,使得未授權的使用者即使獲得了已加密的資訊,但因不知解密的方法,仍然無法瞭解資訊的內容。

加密大體上分為雙向加密單向加密,雙向加密又分為對稱加密非對稱加密

-------------------------------------------------------------------------------------------------------------------------------------------

單向加密演算法

主要介紹BASE64、MD5、SHA、HMAC幾種加密演算法

BASE64編碼演算法不算是真正的加密演算法。

MD5、SHA、HMAC這三種加密演算法,可謂是非可逆加密,就是不可解密的加密方法,我們稱之為單向加密演算法。

我們通常只把他們作為加密的基礎。單純的以上三種的加密並不可靠。

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程式碼實現如下:

	/**
	 * BASE64解密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptBASE64(String key) throws Exception {
		return (new BASE64Decoder()).decodeBuffer(key);
	}

	/**
	 * BASE64加密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptBASE64(byte[] key) throws Exception {
		return (new BASE64Encoder()).encodeBuffer(key);
	}
主要就是BASE64Encoder、BASE64Decoder兩個類,我們只需要知道使用對應的方法即可,另Base64加密後產生的位元組位數是8的倍數,如果不夠位數以=符號填充

MD5
MD5--message-digest algorithm 5 (資訊-摘要演算法)縮寫,廣泛使用者加密和解密技術,常用於檔案校驗。

校驗?不管檔案多大,經過MD5後都能生成唯一的MD5值。好比現在的ISO校驗,都是MD5校驗。

怎麼用?當然是把ISO經過MD5後產生MD5的值。一般下載linux-iso的朋友都見過下載連結旁邊放著MD5串。就是為了校驗檔案是否一致的。


通過Java程式碼實現

	/**
	 * MD5加密
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptMD5(byte[] data) throws Exception {

		MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
		md5.update(data);

		return md5.digest();

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

SHA

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


通過Java程式碼實現如下:

	/**
	 * SHA加密
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptSHA(byte[] data) throws Exception {

		MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
		sha.update(data);

		return sha.digest();

	}
}

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


通過java程式碼實現:

	/**
	 * 初始化HMAC金鑰
	 * 
	 * @return
	 * @throws Exception
	 */
	public static String initMacKey() throws Exception {
		KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);

		SecretKey secretKey = keyGenerator.generateKey();
		return encryptBASE64(secretKey.getEncoded());
	}

	/**
	 * HMAC加密
	 * 
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptHMAC(byte[] data, String key) throws Exception {

		SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
		Mac mac = Mac.getInstance(secretKey.getAlgorithm());
		mac.init(secretKey);

		return mac.doFinal(data);

	}

給出一個完整的類,如下:
import java.security.MessageDigest;

import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * 基礎加密元件
 * 
 * @author 樑棟
 * @version 1.0
 * @since 1.0
 */
public abstract class Coder {
	public static final String KEY_SHA = "SHA";
	public static final String KEY_MD5 = "MD5";

	/**
	 * MAC演算法可選以下多種演算法
	 * 
	 * <pre>
	 * HmacMD5 
	 * HmacSHA1 
	 * HmacSHA256 
	 * HmacSHA384 
	 * HmacSHA512
	 * </pre>
	 */
	public static final String KEY_MAC = "HmacMD5";

	/**
	 * BASE64解密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] decryptBASE64(String key) throws Exception {
		return (new BASE64Decoder()).decodeBuffer(key);
	}

	/**
	 * BASE64加密
	 * 
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptBASE64(byte[] key) throws Exception {
		return (new BASE64Encoder()).encodeBuffer(key);
	}

	/**
	 * MD5加密
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptMD5(byte[] data) throws Exception {

		MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
		md5.update(data);

		return md5.digest();

	}

	/**
	 * SHA加密
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptSHA(byte[] data) throws Exception {

		MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
		sha.update(data);

		return sha.digest();

	}

	/**
	 * 初始化HMAC金鑰
	 * 
	 * @return
	 * @throws Exception
	 */
	public static String initMacKey() throws Exception {
		KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);

		SecretKey secretKey = keyGenerator.generateKey();
		return encryptBASE64(secretKey.getEncoded());
	}

	/**
	 * HMAC加密
	 * 
	 * @param data
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static byte[] encryptHMAC(byte[] data, String key) throws Exception {

		SecretKey secretKey = new SecretKeySpec(decryptBASE64(key), KEY_MAC);
		Mac mac = Mac.getInstance(secretKey.getAlgorithm());
		mac.init(secretKey);

		return mac.doFinal(data);

	}
}
測試類:
import static org.junit.Assert.*;

import org.junit.Test;

/**
 * 
 * @author 樑棟
 * @version 1.0
 * @since 1.0
 */
public class CoderTest {

	@Test
	public void test() throws Exception {
		String inputStr = "簡單加密";
		System.err.println("原文:\n" + inputStr);

		byte[] inputData = inputStr.getBytes();
		String code = Coder.encryptBASE64(inputData);

		System.err.println("BASE64加密後:\n" + code);

		byte[] output = Coder.decryptBASE64(code);

		String outputStr = new String(output);

		System.err.println("BASE64解密後:\n" + outputStr);

		// 驗證BASE64加密解密一致性
		assertEquals(inputStr, outputStr);

		// 驗證MD5對於同一內容加密是否一致
		assertArrayEquals(Coder.encryptMD5(inputData), Coder
				.encryptMD5(inputData));

		// 驗證SHA對於同一內容加密是否一致
		assertArrayEquals(Coder.encryptSHA(inputData), Coder
				.encryptSHA(inputData));

		String key = Coder.initMacKey();
		System.err.println("Mac金鑰:\n" + key);

		// 驗證HMAC對於同一內容,同一金鑰加密是否一致
		assertArrayEquals(Coder.encryptHMAC(inputData, key), Coder.encryptHMAC(
				inputData, key));

		BigInteger md5 = new BigInteger(Coder.encryptMD5(inputData));
		System.err.println("MD5:\n" + md5.toString(16));

		BigInteger sha = new BigInteger(Coder.encryptSHA(inputData));
		System.err.println("SHA:\n" + sha.toString(32));

		BigInteger mac = new BigInteger(Coder.encryptHMAC(inputData, inputStr));
		System.err.println("HMAC:\n" + mac.toString(16));
	}
}
控制檯輸出:
原文:
簡單加密
BASE64加密後:
566A5Y2V5Yqg5a+G

BASE64解密後:
簡單加密
Mac金鑰:
uGxdHC+6ylRDaik++leFtGwiMbuYUJ6mqHWyhSgF4trVkVBBSQvY/a22xU8XT1RUemdCWW155Bke
pBIpkd7QHg==

MD5:
-550b4d90349ad4629462113e7934de56
SHA:
91k9vo7p400cjkgfhjh0ia9qthsjagfn
HMAC:
2287d192387e95694bdbba2fa941009a

BASE64的加密是雙向的,可以求反解。

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

  單向加密的用途主要是為了校驗資料在傳輸過程中是否被修改。

----------------------------------------------------------------------------------------------------------------------------------

一、雙向加密
(一)、對稱加密
採用單鑰密碼系統的加密方法,同一個金鑰可以同時用作資訊的加密和解密,這種加密方法稱為對稱加密,也稱為單金鑰加密。 
需要對加密和解密使用相同金鑰的加密演算法。由於其速度,對稱性加密通常在訊息傳送方需要加密大量資料時使用。對稱性加密也稱為金鑰加密。 
所謂對稱,就是採用這種加密方法的雙方使用方式用同樣的金鑰進行加密和解密。金鑰是控制加密及解密過程的指令。 

演算法是一組規則,規定如何進行加密和解密。因此對稱式加密本身不是安全的。    
常用的對稱加密有:DES、IDEA、RC2、RC4、SKIPJACK、RC5、AES演算法等 

對稱加密一般java類中中定義成員 

Java程式碼  收藏程式碼
  1. //KeyGenerator 提供對稱金鑰生成器的功能,支援各種演算法  
  2. private KeyGenerator keygen;  
  3. //SecretKey 負責儲存對稱金鑰  
  4. private SecretKey deskey;  
  5. //Cipher負責完成加密或解密工作  
  6. private Cipher c;  
  7. //該位元組陣列負責儲存加密的結果  
  8. private byte[] cipherByte;  

在建構函式中初始化 
Java程式碼  收藏程式碼
  1. Security.addProvider(new com.sun.crypto.provider.SunJCE());  
  2. //例項化支援DES演算法的金鑰生成器(演算法名稱命名需按規定,否則丟擲異常)  
  3. keygen = KeyGenerator.getInstance("DES");//  
  4. //生成金鑰  
  5. deskey = keygen.generateKey();  
  6. //生成Cipher物件,指定其支援的DES演算法  
  7. c = Cipher.getInstance("DES");  


1. DES演算法為密碼體制中的對稱密碼體制,又被成為美國資料加密標準,是1972年美國IBM公司研製的對稱密碼體制加密演算法。 明文按64位進行分組, 金鑰長64位,金鑰事實上是56位參與DES運算(第8、16、24、32、40、48、56、64位是校驗位, 使得每個金鑰都有奇數個1)分組後的明文組和56位的金鑰按位替代或交換的方法形成密文組的加密方法。 

Java程式碼  收藏程式碼
  1. import java.security.InvalidKeyException;  
  2. import java.security.NoSuchAlgorithmException;  
  3. import java.security.Security;  
  4. import javax.crypto.BadPaddingException;  
  5. import javax.crypto.Cipher;  
  6. import javax.crypto.IllegalBlockSizeException;  
  7. import javax.crypto.KeyGenerator;  
  8. import javax.crypto.NoSuchPaddingException;  
  9. import javax.crypto.SecretKey;  
  10. public class EncrypDES {  
  11.     //KeyGenerator 提供對稱金鑰生成器的功能,支援各種演算法  
  12.     private KeyGenerator keygen;  
  13.     //SecretKey 負責儲存對稱金鑰  
  14.     private SecretKey deskey;  
  15.     //Cipher負責完成加密或解密工作  
  16.     private Cipher c;  
  17.     //該位元組陣列負責儲存加密的結果  
  18.     private byte[] cipherByte;  
  19.     public EncrypDES() throws NoSuchAlgorithmException, NoSuchPaddingException{  
  20.         Security.addProvider(new com.sun.crypto.provider.SunJCE());  
  21.         //例項化支援DES演算法的金鑰生成器(演算法名稱命名需按規定,否則丟擲異常)  
  22.         keygen = KeyGenerator.getInstance("DES");  
  23.         //生成金鑰  
  24.         deskey = keygen.generateKey();  
  25.         //生成Cipher物件,指定其支援的DES演算法  
  26.         c = Cipher.getInstance("DES");  
  27.     }  
  28.     /** 
  29.      * 對字串加密 
  30.      *  
  31.      * @param str 
  32.      * @return 
  33.      * @throws InvalidKeyException 
  34.      * @throws IllegalBlockSizeException 
  35.      * @throws BadPaddingException 
  36.      */  
  37.     public byte[] Encrytor(String str) throws InvalidKeyException,  
  38.             IllegalBlockSizeException, BadPaddingException {  
  39.         // 根據金鑰,對Cipher物件進行初始化,ENCRYPT_MODE表示加密模式  
  40.         c.init(Cipher.ENCRYPT_MODE, deskey);  
  41.         byte[] src = str.getBytes();  
  42.         // 加密,結果儲存進cipherByte  
  43.         cipherByte = c.doFinal(src);  
  44.         return cipherByte;  
  45.     }  
  46.     /** 
  47.      * 對字串解密 
  48.      *  
  49.      * @param buff 
  50.      * @return 
  51.      * @throws InvalidKeyException 
  52.      * @throws IllegalBlockSizeException 
  53.      * @throws BadPaddingException 
  54.      */  
  55.     public byte[] Decryptor(byte[] buff) throws InvalidKeyException,  
  56.             IllegalBlockSizeException, BadPaddingException {  
  57.         // 根據金鑰,對Cipher物件進行初始化,DECRYPT_MODE表示加密模式  
  58.         c.init(Cipher.DECRYPT_MODE, deskey);  
  59.         cipherByte = c.doFinal(buff);  
  60.         return cipherByte;  
  61.     }  
  62.     /** 
  63.      * @param args 
  64.      * @throws NoSuchPaddingException  
  65.      * @throws NoSuchAlgorithmException  
  66.      * @throws BadPaddingException  
  67.      * @throws IllegalBlockSizeException  
  68.      * @throws InvalidKeyException  
  69.      */  
  70.     public static void main(String[] args) throws Exception {  
  71.         EncrypDES de1 = new EncrypDES();  
  72.         String msg ="郭XX-搞笑相聲全集";  
  73.         byte[] encontent = de1.Encrytor(msg);  
  74.         byte[] decontent = de1.Decryptor(encontent);  
  75.         System.out.println("明文是:" + msg);  
  76.         System.out.println("加密後:" + new String(encontent));  
  77.         System.out.println("解密後:" + new String(decontent));  
  78.     }  
  79. }  


2. 3DES又稱Triple DES,是DES加密演算法的一種模式,它使用3條56位的金鑰對3DES 
資料進行三次加密。資料加密標準(DES)是美國的一種由來已久的加密標準,它使用對稱金鑰加密法,並於1981年被ANSI組織規範為ANSI X.3.92。DES使用56位金鑰和密碼塊的方法,而在密碼塊的方法中,文字被分成64位大小的文字塊然後再進行加密。比起最初的DES,3DES更為安全。    
3DES(即Triple DES)是DES向AES過渡的加密演算法(1999年,NIST將3-DES指定為過渡的加密標準),是DES的一個更安全的變形。它以DES為基本模組,通過組合分組方法設計出分組加密演算法,其具體實現如下: 
設Ek()和Dk()代表DES演算法的加密和解密過程,K代表DES演算法使用的金鑰,P代表明文,C代表密文, 
這樣,    
3DES加密過程為:C=Ek3(Dk2(Ek1(P))) 
3DES解密過程為:P=Dk1((EK2(Dk3(C))) 
Java程式碼  收藏程式碼
  1. import java.security.InvalidKeyException;  
  2. import java.security.NoSuchAlgorithmException;  
  3. import java.security.Security;  
  4. import javax.crypto.BadPaddingException;  
  5. import javax.crypto.Cipher;  
  6. import javax.crypto.IllegalBlockSizeException;  
  7. import javax.crypto.KeyGenerator;  
  8. import javax.crypto.NoSuchPaddingException;  
  9. import javax.crypto.SecretKey;  
  10. public class EncrypDES3 {  
  11.     // KeyGenerator 提供對稱金鑰生成器的功能,支援各種演算法  
  12.     private KeyGenerator keygen;  
  13. 相關推薦

    JAVADES加密方式示例

    本問只簡要講解在JAVA中如何使用幾種加密的程式碼示例,關於加密演算法和數學知識不在本文討論範圍。 package com.util; import java.security.NoSuchAlgorithmException; import java.secu

    Java常用加密方式

    加密,是以某種特殊的演算法改變原有的資訊資料,使得未授權的使用者即使獲得了已加密的資訊,但因不知解密的方法,仍然無法瞭解資訊的內容。 加密大體上分為雙向加密和單向加密,雙向加密又分為對稱加密和非對稱加密 ------------------------------

    Java常用加密算法小結

    單向 安全 加密算法 對稱 digest iges 公鑰加密 非對稱加密 algorithm 散列算法(單向散列,不可逆) MD5(Message Digest Algorithm 5) SHA(Secure Hash Algorithm) 對稱加密(加密解密

    Java常用加密與解密方法

    加密,是以某種特殊的演算法改變原有的資訊資料,使得未授權的使用者即使獲得了已加密的資訊,但因不知解密的方法,仍然無法瞭解資訊的內容。大體上分為雙向加密和單向加密,而雙向加密又分為對稱加密和非對稱加密(有些資料將加密直接分為對稱加密和非對稱加密)。 雙向加密大體意思就是明文加

    java常用的對稱加密演算法

    一 常用的對稱加密演算法 對稱加密演算法簡單來講就是加密和解密使用同一個金鑰,並且加密解密互為逆運算,如加法和減法,先加密再解密 與先解密後加密都能得到原結果,常用的加密演算法有DES;3DES(二倍長,三倍長);AES; 3DES是DES擴充套件,3D

    Java常用加密與解密方法《轉載》

    加密,是以某種特殊的演算法改變原有的資訊資料,使得未授權的使用者即使獲得了已加密的資訊,但因不知解密的方法,仍然無法瞭解資訊的內容。大體上分為雙向加密和單向加密,而雙向加密又分為對稱加密和非對稱加密(有些資料將加密直接分為對稱加密和非對稱加密)。 雙向加密大體意思就是明文加密

    Javamd5加密

    com char common span edi case codec mdt imp 方法一、 public final static String md5(String s) { char hexDigits[] = {‘0‘,‘1‘,‘2‘,‘

    Java 常用的數據源

    tools xml文件 安裝目錄 建立數據庫 container word classname highlight attribute 數據源:存儲了所有建立數據庫連接的信息。就象通過指定文件名你可以在文件系統中找到文件一樣,通過提供正確的數據源名稱,你可以找到相應的數據庫

    JaVa常用緩存CaCHE機制

    ava lis hao123 java 緩存cache 機制 http .com list %E5%85%B3%E4%BA%8E%E5%9B%9E%E8%B0%83%E5%87%BD%E6%95%B0%E5%8F%82%E6%95%B0%E7%9A%84%E9%97%AE%

    關於java get提交方式的亂碼問題

    文字 問題 block eth 重新 clas 指定 原因 getpara 這個原因是服務器導致的,服務器比如tomcat接收get方法默認使用的是ISO-8859-1編碼,而瀏覽器發送時文字編碼是和頁面編碼保持一致的,如果頁面是使用utf-8 編碼 get方法文字自然是

    java常用jar包

    中一 2.6 jdb jxl obj 串行化 分析 lean tag commons-io.jar:可以看成是java.io的擴展,用來幫助進行IO功能開發.它包含三個主要的領域:Utilityclasses-提供一些靜態方法來完成公共任務.Filters-提供文件過濾器的

    JAVA常用IO流類:FileInputStream和FileOutputStream

    table string [] 文件中 讀取 描述符 off fis 系統資源 FileInputStream 用於讀取本地文件中的字節數據,繼承自InputStream類 構造方法摘要 FileInputStream(File file) 通

    【知了堂學習筆記】java常用集合的理解

    style out hset 篩選 arraylist list 內容 必備 foreach   最近學習了java中常用集合類的一些知識,在這裏作為一只小白,我來談談我的理解,順帶總結知識點。 引入:在沒有接觸之前,聽到集合,給我感覺是想到了數學中的集合一樣,裏面存放著一

    php和java加密和解密

    padding 而不是 bsp enc openss 解密 div des算法 -c 遇到的java代碼如下: Cipher cipher=Cipher.getInstance("DESede/CBC/PKCS5Padding"); 在php中使用des算法 始終校驗不

    Java動態代理方式

    tint lap cto getname AI clas tcl show this JDK中生成代理對象的API 代理類所在包:java.lang.reflect.ProxyJDK實現代理只需要使用newProxyInstance方法,但是該方法需要接收三個參數,完整的

    java常用的進制轉換

    eof 十六 轉換 hex integer nbsp tostring obi int 十進制轉成十六進制: Integer.toHexString(int i) 十進制轉成八進制 Integer.toOctalString(int i) 十進制轉成二進制

    開發java常用的幾種數據類型

    api dep 同步問題 end ike 文檔 添加 nbsp gravity JAVA中常用的數據結構(java.util. 中) java中有幾種常用的數據結構,主要分為Collection和map兩個主要接口(接口只提供方法,並不提供實現),而程序中最終使用的數

    009-java常用的單個鍵值對

    RKE tab string class lan integer eva guava 鍵值對 1、Java 6提供AbstractMap.SimpleEntry<K,V>和AbstractMap.SimpleImmutableEntry<K,V>

    Java常用的API總結

    Java API是JDK所提供的使用類,這些類將底層的程式碼給封裝起來了。Object類是java語言中的根類,它所描述的所有方法子類都可以使用,所有類在建立物件的時候,最終找的父類就是Object。在Objec類中,最常見的就是euqals方法和toString方法。equals方法用於比較兩個物

    Java常用的異常處理情況及關於開發異常處理的建議

    cloneabl 軟件 完整性 內置 加載類 異常信息 dstat 應用程序 dsta 本周四老師由一個簡單程序將問題引出,講授了Java中異常處理的情況。根據課件內容及上網查閱資料,將關於JAVA項目中的常用的異常處理情況總結如下: 首先什麽是異常(Exception