三、DES解密
idea中使用 ctrl + alt + m 快捷鍵抽取代碼
package com.atguigu.desaes;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* @author JsonHao😋
* @date 2020年9月11日 下午9:22:52
*/
public class DesDemo {
// DES加密算法,key的大小必須是8個位元組
public static void main(String[] args) throws Exception {
String input ="矽谷";
// DES加密算法,key的大小必須是8個位元組
String key = "12345678";
String transformation = "DES"; // 9PQXVUIhaaQ=
// 指定擷取密鑰的算法
String algorithm = "DES";
String encryptDES = encryptDES(input, key, transformation, algorithm);
System.out.println("加密:" + encryptDES);
String s = decryptDES(encryptDES, key, transformation, algorithm);
System.out.println("解密:" + s);
}
/**
* 使用DES加密資料
*
* @param input : 原文
* @param key : 密鑰(DES,密鑰的長度必須是8個位元組)
* @param transformation : 擷取Cipher對象的算法
* @param algorithm : 擷取密鑰的算法
* @return : 密文
* @throws Exception
*/
private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
// 擷取加密對象
Cipher cipher = Cipher.getInstance(transformation);
// 建立加密規則
// 第一個參數key的位元組
// 第二個參數表示加密算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// ENCRYPT_MODE:加密模式
// DECRYPT_MODE: 解密模式
// 初始化加密模式和算法
cipher.init(Cipher.ENCRYPT_MODE,sks);
// 加密
byte[] bytes = cipher.doFinal(input.getBytes());
// 輸出加密後的資料
String encode = Base64.encode(bytes);
return encode;
}
/**
* 使用DES解密
*
* @param input : 密文
* @param key : 密鑰
* @param transformation : 擷取Cipher對象的算法
* @param algorithm : 擷取密鑰的算法
* @throws Exception
* @return: 原文
*/
private static String decryptDES(String input, String key, String transformation, String algorithm) throws Exception {
// 1,擷取Cipher對象
Cipher cipher = Cipher.getInstance(transformation);
// 指定密鑰規則
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
cipher.init(Cipher.DECRYPT_MODE, sks);
// 3. 解密,上面使用的base64編碼,下面直接用密文
byte[] bytes = cipher.doFinal(Base64.decode(input));
// 因為是明文,是以直接傳回
return new String(bytes);
}
}
四、base64補等号測試
package com.atguigu;
import com.sun.org.apache.xml.internal.security.utils.Base64;
/**
* @author JsonHao😋
* @date 2020年9月11日 下午9:30:20
*/
public class TestBase64 {
public static void main(String[] args) {
// 1:MQ== 表示一個位元組,不夠三個位元組,是以需要後面通過 == 号補齊
System.out.println(Base64.encode("1".getBytes()));
System.out.println(Base64.encode("12".getBytes()));
System.out.println(Base64.encode("123".getBytes()));
// // 矽谷:中文占6個位元組,6 * 8 = 48 ,剛剛好被整除,是以沒有等号
System.out.println(Base64.encode("矽谷".getBytes()));
}
}
五、AES加密解密
AES 加密解密和 DES 加密解密代碼一樣,隻需要修改加密算法就行,拷貝 ESC 代碼
package com.atguigu.desaes;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
/**
* @author JsonHao😋
* @date 2020年9月11日 下午9:34:48
*/
public class AesDemo {
// DES加密算法,key的大小必須是8個位元組
public static void main(String[] args) throws Exception {
String input ="矽谷";
// AES加密算法,比較進階,是以key的大小必須是16個位元組
String key = "1234567812345678";
String transformation = "AES"; // 9PQXVUIhaaQ=
// 指定擷取密鑰的算法
String algorithm = "AES";
// 先測試加密,然後在測試解密
String encryptDES = encryptDES(input, key, transformation, algorithm);
System.out.println("加密:" + encryptDES);
String s = dncryptDES(encryptDES, key, transformation, algorithm);
System.out.println("解密:" + s);
}
/**
* 使用DES加密資料
*
* @param input : 原文
* @param key : 密鑰(DES,密鑰的長度必須是8個位元組)
* @param transformation : 擷取Cipher對象的算法
* @param algorithm : 擷取密鑰的算法
* @return : 密文
* @throws Exception
*/
private static String encryptDES(String input, String key, String transformation, String algorithm) throws Exception {
// 擷取加密對象
Cipher cipher = Cipher.getInstance(transformation);
// 建立加密規則
// 第一個參數key的位元組
// 第二個參數表示加密算法
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
// ENCRYPT_MODE:加密模式
// DECRYPT_MODE: 解密模式
// 初始化加密模式和算法
cipher.init(Cipher.ENCRYPT_MODE,sks);
// 加密
byte[] bytes = cipher.doFinal(input.getBytes());
// 輸出加密後的資料
String encode = Base64.encode(bytes);
return encode;
}
/**
* 使用DES解密
*
* @param input : 密文
* @param key : 密鑰
* @param transformation : 擷取Cipher對象的算法
* @param algorithm : 擷取密鑰的算法
* @throws Exception
* @return: 原文
*/
private static String dncryptDES(String input, String key, String transformation, String algorithm) throws Exception {
// 1,擷取Cipher對象
Cipher cipher = Cipher.getInstance(transformation);
// 指定密鑰規則
SecretKeySpec sks = new SecretKeySpec(key.getBytes(), algorithm);
cipher.init(Cipher.DECRYPT_MODE, sks);
// 3. 解密
byte[] bytes = cipher.doFinal(Base64.decode(input));
return new String(bytes);
}
}
運作結果是
MM#WLAN#Uc+9lGbR6e5N9hrtm7CA+A==#646465698#399900003000
[B@1540e19d
哪一個是正确的?為什麼?
這裡應該用new String()的方法,因為Base64加解密是一種轉換編碼格式的原理
toString()與new String ()用法差別
str.toString是調用了這個object對象的類的toString方法。一般是傳回這麼一個String:[class name]@[hashCode]
new String(str)是根據parameter是一個位元組數組,使用java虛拟機預設的編碼格式,将這個位元組數組decode為對應的字元。若虛拟機預設的編碼格式是ISO-8859-1,按照ascii編碼表即可得到位元組對應的字元。
什麼時候用什麼方法呢?
new String()一般使用字元轉碼的時候,byte[]數組的時候
toString()對象列印的時候使用