Java之DES加解密解析

  說明:上篇RSA是一種非對稱的加解密算法,今天這種是一種對稱的加解密算法DESDES算法的入口參數有三個:Key、Data、Mode。其中Key爲7個字節共56位,是DES算法的工做密鑰;Data爲8個字節64位,是要被加密或被解密的數據;Mode爲DES的工做方式,有兩種:加密或解密。Java裏封裝了不少種對稱加密算法的使用,這裏以DES爲例。java

1、什麼是對稱算法


  對稱密碼算法有時又叫傳統密碼算法,就是加密密鑰可以從解密密鑰中推算出來,反過來也成立。加密與解密互逆,在大多數對稱算法中,加密解密密鑰是相同的。 算法

在這裏插入圖片描述
圖 1

優勢:效率高(加/解密速度能達到數十兆/秒或更多),算法簡單,系統開銷小,適合加密大量數據。 缺點:進行安全通訊前須要以安全方式進行密鑰交換,安全得不到有效保證,規模旁雜。數組


2、密鑰的機制


  DES密鑰初始化的長度是64位,而實際可用的位置是56位,由於DES算法規定,第八、1六、……64位是奇偶校驗位,不參與DES運算。安全

一、初始序化Key的長度 bash

在這裏插入圖片描述
圖 2

因此這裏最好不要去指定長度了,默認的就是56了。app

二、若是指定的key超過64位有啥影響 測試

在這裏插入圖片描述
圖 3

在這裏插入圖片描述
圖 4

  經過上面圖三、圖4對比可知(加密後序列同樣,你們能夠直接把生成key序列16進制打出來更直觀),初始的key序列超過8字節64位,會自動截取掉,後面多餘長度不參與key生成。ui

三、不一樣的加密序列加密後結果同樣 加密

在這裏插入圖片描述
圖 5

  參考圖三、圖5將字節數組中的18->19,發現加密後的序列徹底同樣。啥緣由呢?在上面已經提到過,DES實現中第八、1六、32... 64位爲校驗位,至關於只是用每一個字節中的前7位進行生成;將1八、19轉化爲二進制爲00010010 、00010011 而後去掉最後一位,能夠發現前7位是同樣的。因此這樣解釋了爲何有時候加密序列不一樣,加密後的內容倒是徹底同樣。spa


3、完整的DEMO


   若是讓Base64具備加解密的功能,至少要一部分是變化的;這裏能夠經過變化標準序列的方式;建議你們用到的時候,能夠先看一下第3部分中標出那個類的源碼(沒幾行代碼);這個變化的序列能夠根據時間、根據UUID、根據一切能夠變換的東西來生成,這裏是根據UUID來隨機生成序列。    一、生成隨機序列

package c.d.des;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
public class DesTest {
	Cipher cipher = null;
	public DesTest() {
		init();
	}
	public void init() {
		try {
			KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
			keyGenerator.init(56);
			cipher = Cipher.getInstance("DES");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	// 二進制轉換字符串
	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}
	// 獲取Key
	public Key getKey(byte[] passKey) {
		Key convertSecretKey = null;
		try {
			DESKeySpec deSedeKeySpec = new DESKeySpec(passKey);
			SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
			convertSecretKey = factory.generateSecret(deSedeKeySpec);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return convertSecretKey;
	}
	// 加密
	public byte[] encode(byte[] source, Key key) throws Exception {
		cipher.init(Cipher.ENCRYPT_MODE, key);
		byte[] encodeSource = cipher.doFinal(source);
		return encodeSource;
	}
	// 解密
	public String decode(byte[] encodeSource, Key key) throws Exception {
		cipher.init(Cipher.DECRYPT_MODE, key);
		byte[] decodeRes = cipher.doFinal(encodeSource);
		return new String(decodeRes, "UTF-8");
	}
	public static void main(String[] args) throws Exception {
		DesTest dt = new DesTest();
		byte[] passKey = new byte[] {11, 12, 13, 14, 15, 16, 17,18,19,20 };
		System.out.println(passKey.length);
		Key key = dt.getKey(passKey);
		String obj = "就先測試這句吧";
		System.out.println("加密前:" + obj);
		byte[] source = dt.encode(obj.getBytes("UTF-8"), key);
		System.out.println("加密後:" + bytesToHexString(source));
		String res = dt.decode(source, key);
		System.out.println("解密後:" + res);
		String s1 = "0815d22bf5ae0bdd9d37594cedd4be6c1fead86115544517";
		String s2 = "0815d22bf5ae0bdd9d37594cedd4be6c1fead86115544517";
		System.out.println(s1.equals(s2));
	}
}

複製代碼

4、後續


   既然DES經過暴力一天即可破解,那麼3DES如何?你們能夠自行研究一下,和DES相似。


持續更新中,能夠關注........

javaview.jpg
相關文章
相關標籤/搜索