更新時間:2022-05-10 11:14:20 來源:動力節點 瀏覽4057次
常用的Java加密和解密方式有哪些?動力節點小編來告訴你。
Base64 編碼是我們程序開發中經常使用到的編碼方法,它用 64 個可打印字符來表示二進制數據。這 64 個字符是:小寫字母 a-z、大寫字母 A-Z、數字 0-9、符號"+"、"/"(再加上作為墊字的"=",實際上是 65 個字符),其他所有符號都轉換成這個字符集中的字符。Base64 編碼通常用作存儲、傳輸一些二進制數據編碼方法,所以說它本質上是一種將二進制數據轉成文本數據的方案。
通常用作對二進制數據進行加密,示例:
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Base64Util {
/***
* BASE64解密
* @param key
* @return
* @throws Exception
*/
public static byte[] decryBASE64(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()).encode(key);
}
}
MD5 是將任意長度的數據字符串轉化成短小的固定長度的值的單向操作,任意兩個字符串不應有相同的散列值。因此 MD5 經常用于校驗字符串或者文件,因為如果文件的 MD5 不一樣,說明文件內容也是不一樣的,如果發現下載的文件和給定的 MD5 值不一樣,就要慎重使用。
MD5 主要用做數據一致性驗證、數字簽名和安全訪問認證,而不是用作加密。比如說用戶在某個網站注冊賬戶時,輸入的密碼一般經過 MD5 編碼,更安全的做法還會加一層鹽(salt),這樣密碼就具有不可逆性。然后把編碼后的密碼存入數據庫,下次登錄的時候把密碼 MD5 編碼,然后和數據庫中的作對比,這樣就提升了用戶賬戶的安全性。
是一種單向加密算法,只能加密不能解密,示例:
import java.security.MessageDigest;
public class MD5Util {
public static final String KEY_MD5 = "MD5";
/***
* MD5加密(生成唯一的MD5值)
* @param data
* @return
* @throws Exception
*/
public static byte[] encryMD5(byte[] data) throws Exception {
MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
md5.update(data);
return md5.digest();
}
}
DES 是一種對稱加密算法,所謂對稱加密算法就是:加密和解密使用相同密鑰的算法。DES 加密算法出自 IBM 的研究,后來被美國政府正式采用,之后開始廣泛流傳。但近些年使用越來越少,因為 DES 使用 56 位密鑰,以現代的計算能力,24 小時內即可被破解。
順便說一下 3DES(Triple DES),它是 DES 向 AES 過渡的加密算法,使用 3 條 56 位的密鑰對數據進行三次加密。是 DES 的一個更安全的變形。它以 DES 為基本模塊,通過組合分組方法設計出分組加密算法。比起最初的 DES,3DES 更為安全。
使用 Java 實現 DES 加密解密,注意密碼長度要是 8 的倍數。加密和解密的 Cipher 構造參數一定要相同,不然會報錯。
數據加密標準算法,和BASE64最明顯的區別就是有一個工作密鑰,該密鑰既用于加密、也用于解密,并且要求密鑰是一個長度至少大于8位的字符串,示例:
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class DesUtil {
private static Key key;
private static String KEY_STR="myKey";
private static String CHARSETNAME="UTF-8";
private static String ALGORITHM="DES";
static {
try {
//生成DES算法對象
KeyGenerator generator=KeyGenerator.getInstance(ALGORITHM);
//運用SHA1安全策略
SecureRandom secureRandom=SecureRandom.getInstance("SHA1PRNG");
//設置上密鑰種子
secureRandom.setSeed(KEY_STR.getBytes());
//初始化基于SHA1的算法對象
generator.init(secureRandom);
//生成密鑰對象
key=generator.generateKey();
generator=null;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/***
* 獲取加密的信息
* @param str
* @return
*/
public static String getEncryptString(String str) {
//基于BASE64編碼,接收byte[]并轉換成String
BASE64Encoder encoder = new BASE64Encoder();
try {
//按utf8編碼
byte[] bytes = str.getBytes(CHARSETNAME);
//獲取加密對象
Cipher cipher = Cipher.getInstance(ALGORITHM);
//初始化密碼信息
cipher.init(Cipher.ENCRYPT_MODE, key);
//加密
byte[] doFinal = cipher.doFinal(bytes);
//byte[]to encode好的String 并返回
return encoder.encode(doFinal);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/***
* 獲取解密之后的信息
* @param str
* @return
*/
public static String getDecryptString(String str) {
BASE64Decoder decoder = new BASE64Decoder();
try {
//將字符串decode成byte[]
byte[] bytes = decoder.decodeBuffer(str);
//獲取解密對象
Cipher cipher = Cipher.getInstance(ALGORITHM);
//初始化解密信息
cipher.init(Cipher.DECRYPT_MODE, key);
//解密
byte[] doFial = cipher.doFinal(bytes);
return new String(doFial, CHARSETNAME);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱 Rijndael 加密法,是美國聯邦政府采用的一種區塊加密標準。這個標準用來替代原先的 DES,已經被多方分析且廣為全世界所使用。簡單說就是 DES 的增強版,比 DES 的加密強度更高。
AES 與 DES 一樣,一共有四種加密模式:電子密碼本模式(ECB)、加密分組鏈接模式(CBC)、加密反饋模式(CFB)和輸出反饋模式(OFB)。
示例代碼:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AESUtil {
public static final String algorithm = "AES";
// AES/CBC/NOPaddin
// AES 默認模式
// 使用CBC模式, 在初始化Cipher對象時, 需要增加參數, 初始化向量IV : IvParameterSpec iv = new
// IvParameterSpec(key.getBytes());
// NOPadding: 使用NOPadding模式時, 原文長度必須是8byte的整數倍
public static final String transformation = "AES/CBC/NOPadding";
public static final String key = "1234567812345678";
/***
* 加密
* @param original 需要加密的參數(注意必須是16位)
* @return
* @throws Exception
*/
public static String encryptByAES(String original) throws Exception {
// 獲取Cipher
Cipher cipher = Cipher.getInstance(transformation);
// 生成密鑰
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
// 指定模式(加密)和密鑰
// 創建初始化向量
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
// cipher.init(Cipher.ENCRYPT_MODE, keySpec);
// 加密
byte[] bytes = cipher.doFinal(original.getBytes());
return Base64Util.encryptBASE64(bytes);
}
/**
* 解密
* @param encrypted 需要解密的參數
* @return
* @throws Exception
*/
public static String decryptByAES(String encrypted) throws Exception {
// 獲取Cipher
Cipher cipher = Cipher.getInstance(transformation);
// 生成密鑰
SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
// 指定模式(解密)和密鑰
// 創建初始化向量
IvParameterSpec iv = new IvParameterSpec(key.getBytes());
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
// cipher.init(Cipher.DECRYPT_MODE, keySpec);
// 解密
byte[] bytes = cipher.doFinal(Base64Util.decryBASE64(encrypted));
return new String(bytes);
}
}
使用一個密鑰生成一個固定大小的小數據塊,即MAC,并將其加入到消息中,然后傳輸。接收方利用與發送方共享的密鑰進行鑒別認證,示例:
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class HMACUtil {
public static final String KEY_MAC = "HmacMD5";
/***
* 初始化HMAC密鑰
* @return
* @throws Exception
*/
public static String initMacKey() throws Exception{
KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
SecretKey secreKey = keyGenerator.generateKey();
return Base64Util.encryptBASE64(secreKey.getEncoded());
}
/**
* HMAC加密
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryHMAC(byte[] data, String key) throws Exception{
SecretKey secreKey = new SecretKeySpec(Base64Util.decryBASE64(key), KEY_MAC);
Mac mac = Mac.getInstance(secreKey.getAlgorithm());
mac.init(secreKey);
return mac.doFinal();
}
}
在密碼學中,愷撒密碼是一種最簡單并且最廣為人知的加密技術。
它是一種替換加密的技術,明文中的所欲字母都在字母表上向后(或向前)按照一個固定的數目進行偏移后被替換成密文。
例如:當偏移量是3的時候,所有的字母A將被替換成D,B變成E,以此類推。
這個加密方法是以愷撒的名字命名的,當年愷撒曾用此方法與其將軍們進行聯系。
愷撒密碼通常被座位其他更復雜的加密方法中的一個步驟。
示例代碼:
public class KaisaUtil {
/***
* 使用凱撒加密方式加密數據
* @param orignal 原文
* @param key 密鑰
* @return 加密后的字符
*/
private static String encryptKaisa(String orignal, int key) {
//將字符串轉換為數組
char[] chars = orignal.toCharArray();
StringBuffer buffer = new StringBuffer();
//遍歷數組
for(char aChar : chars) {
//獲取字符的ASCII編碼
int asciiCode = aChar;
//偏移數據
asciiCode += key;
//將偏移后的數據轉為字符
char result = (char)asciiCode;
//拼接數據
buffer.append(result);
}
return buffer.toString();
}
/**
* 使用凱撒加密方式解密數據
*
* @param encryptedData :密文
* @param key :密鑰
* @return : 源數據
*/
private static String decryptKaiser(String encryptedData, int key) {
// 將字符串轉為字符數組
char[] chars = encryptedData.toCharArray();
StringBuilder sb = new StringBuilder();
// 遍歷數組
for (char aChar : chars) {
// 獲取字符的ASCII編碼
int asciiCode = aChar;
// 偏移數據
asciiCode -= key;
// 將偏移后的數據轉為字符
char result = (char) asciiCode;
// 拼接數據
sb.append(result);
}
return sb.toString();
}
public static void main(String[] args) {
String str = "open fire";
String encode = encryptKaisa(str, 3);
System.out.println("加密后:"+encode);
String decode = decryptKaiser(encode, 3);
System.out.println("解密后:"+decode);
}
}
SHA全名叫做安全散列算法,是FIPS所認證的安全散列算法。能計算出一個數字消息所對應到的,長度固定的字符串(又稱消息摘要)的算法。且若輸入的消息不同,它們對應到不同字符串的機率很高。
數字簽名等密碼學應用中重要的工具,被廣泛地應用于電子商務等信息安全領域,示例:
import java.security.MessageDigest;
public class SHAUtil {
public static final String KEY_SHA = "SHA";
public static final String ALGORITHM = "SHA-256";
/***
* SHA加密(比MD5更安全)
* @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();
}
public static String SHAEncrypt(final String content) {
try {
MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
byte[] sha_byte = sha.digest(content.getBytes());
StringBuffer hexValue = new StringBuffer();
for (byte b : sha_byte) {
//將其中的每個字節轉成十六進制字符串:byte類型的數據最高位是符號位,通過和0xff進行與操作,轉換為int類型的正整數。
String toHexString = Integer.toHexString(b & 0xff);
hexValue.append(toHexString.length() == 1 ? "0" + toHexString : toHexString);
}
return hexValue.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
//SHA-256加密
public static String SHA256Encrypt(String sourceStr) {
MessageDigest md = null;
try {
md = MessageDigest.getInstance(ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
if (null != md) {
md.update(sourceStr.getBytes());
String digestStr = getDigestStr(md.digest());
return digestStr;
}
return null;
}
private static String getDigestStr(byte[] origBytes) {
String tempStr = null;
StringBuilder stb = new StringBuilder();
for (int i = 0; i < origBytes.length; i++) {
tempStr = Integer.toHexString(origBytes[i] & 0xff);
if (tempStr.length() == 1) {
stb.append("0");
}
stb.append(tempStr);
}
return stb.toString();
}
}
RSA算法是一種非對稱加密算法,所謂非對稱就是該算法需要一對密鑰,若使用其中一個加密,則需要用另一個才能解密。目前它是最有影響力和最常用的公鑰加密算法,能夠抵抗已知的絕大多數密碼攻擊。從提出到現今的三十多年里,經歷了各種攻擊的考驗,逐漸為人們接受,普遍認為是目前最優秀的公鑰方案之一。
該算法基于一個的數論事實:將兩個大質數相乘十分容易,但是想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰。由于進行的都是大數計算,RSA 最快的情況也比 DES 慢上好幾倍,比對應同樣安全級別的對稱密碼算法要慢 1000 倍左右。所以 RSA 一般只用于少量數據加密,比如說交換對稱加密的密鑰。
使用 RSA 加密主要有這么幾步:生成密鑰對、公開公鑰、公鑰加密私鑰解密、私鑰加密公鑰解密。
示例代碼:
import com.sun.org.apache.xml.internal.security.utils.Base64;
import javax.crypto.Cipher;
import org.apache.commons.io.FileUtils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.nio.charset.Charset;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class RsaUtil {
/**
* 生成密鑰對并保存在本地文件中
*
* @param algorithm : 算法
* @param pubPath : 公鑰保存路徑
* @param priPath : 私鑰保存路徑
* @throws Exception
*/
private static void generateKeyToFile(String algorithm, String pubPath, String priPath) throws Exception {
// 獲取密鑰對生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
// 獲取密鑰對
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 獲取公鑰
PublicKey publicKey = keyPair.getPublic();
// 獲取私鑰
PrivateKey privateKey = keyPair.getPrivate();
// 獲取byte數組
byte[] publicKeyEncoded = publicKey.getEncoded();
byte[] privateKeyEncoded = privateKey.getEncoded();
// 進行Base64編碼
String publicKeyString = Base64.encode(publicKeyEncoded);
String privateKeyString = Base64.encode(privateKeyEncoded);
// 保存文件
FileUtils.writeStringToFile(new File(pubPath), publicKeyString, Charset.forName("UTF-8"));
FileUtils.writeStringToFile(new File(priPath), privateKeyString, Charset.forName("UTF-8"));
}
/**
* 從文件中加載公鑰
*
* @param algorithm : 算法
* @param filePath : 文件路徑
* @return : 公鑰
* @throws Exception
*/
private static PublicKey loadPublicKeyFromFile(String algorithm, String filePath) throws Exception {
// 將文件內容轉為字符串
String keyString = FileUtils.readFileToString(new File(filePath), Charset.forName("UTF-8"));
return loadPublicKeyFromString(algorithm, keyString);
}
/**
* 從字符串中加載公鑰
*
* @param algorithm : 算法
* @param keyString : 公鑰字符串
* @return : 公鑰
* @throws Exception
*/
private static PublicKey loadPublicKeyFromString(String algorithm, String keyString) throws Exception {
// 進行Base64解碼
byte[] decode = Base64.decode(keyString);
// 獲取密鑰工廠
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 構建密鑰規范
X509EncodedKeySpec keyspec = new X509EncodedKeySpec(decode);
// 獲取公鑰
return keyFactory.generatePublic(keyspec);
}
/**
* 從文件中加載私鑰
*
* @param algorithm : 算法
* @param filePath : 文件路徑
* @return : 私鑰
* @throws Exception
*/
private static PrivateKey loadPrivateKeyFromFile(String algorithm, String filePath) throws Exception {
// 將文件內容轉為字符串
String keyString = FileUtils.readFileToString(new File(filePath), Charset.forName("UTF-8"));
return loadPrivateKeyFromString(algorithm, keyString);
}
/**
* 從字符串中加載私鑰
*
* @param algorithm : 算法
* @param keyString : 私鑰字符串
* @return : 私鑰
* @throws Exception
*/
private static PrivateKey loadPrivateKeyFromString(String algorithm, String keyString) throws Exception {
// 進行Base64解碼
byte[] decode = Base64.decode(keyString);
// 獲取密鑰工廠
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// 構建密鑰規范
PKCS8EncodedKeySpec keyspec = new PKCS8EncodedKeySpec(decode);
// 生成私鑰
return keyFactory.generatePrivate(keyspec);
}
/**
* 使用密鑰加密數據
*
* @param algorithm : 算法
* @param input : 原文
* @param key : 密鑰
* @param maxEncryptSize : 最大加密長度(需要根據實際情況進行調整)
* @return : 密文
* @throws Exception
*/
private static String encrypt(String algorithm, String input, Key key, int maxEncryptSize) throws Exception {
// 獲取Cipher對象
Cipher cipher = Cipher.getInstance(algorithm);
// 初始化模式(加密)和密鑰
cipher.init(Cipher.ENCRYPT_MODE, key);
// 將原文轉為byte數組
byte[] data = input.getBytes();
// 總數據長度
int total = data.length;
// 輸出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
decodeByte(maxEncryptSize, cipher, data, total, baos);
// 對密文進行Base64編碼
return Base64.encode(baos.toByteArray());
}
/**
* 解密數據
*
* @param algorithm : 算法
* @param encrypted : 密文
* @param key : 密鑰
* @param maxDecryptSize : 最大解密長度(需要根據實際情況進行調整)
* @return : 原文
* @throws Exception
*/
private static String decrypt(String algorithm, String encrypted, Key key, int maxDecryptSize) throws Exception {
// 獲取Cipher對象
Cipher cipher = Cipher.getInstance(algorithm);
// 初始化模式(解密)和密鑰
cipher.init(Cipher.DECRYPT_MODE, key);
// 由于密文進行了Base64編碼, 在這里需要進行解碼
byte[] data = Base64.decode(encrypted);
// 總數據長度
int total = data.length;
// 輸出流
ByteArrayOutputStream baos = new ByteArrayOutputStream();
decodeByte(maxDecryptSize, cipher, data, total, baos);
// 輸出原文
return baos.toString();
}
/**
* 分段處理數據
*
* @param maxSize : 最大處理能力
* @param cipher : Cipher對象
* @param data : 要處理的byte數組
* @param total : 總數據長度
* @param baos : 輸出流
* @throws Exception
*/
private static void decodeByte(int maxSize, Cipher cipher, byte[] data, int total, ByteArrayOutputStream baos) throws Exception {
// 偏移量
int offset = 0;
// 緩沖區
byte[] buffer;
// 如果數據沒有處理完, 就一直繼續
while (total - offset > 0) {
// 如果剩余的數據 >= 最大處理能力, 就按照最大處理能力來加密數據
if (total - offset >= maxSize) {
// 加密數據
buffer = cipher.doFinal(data, offset, maxSize);
// 偏移量向右側偏移最大數據能力個
offset += maxSize;
} else {
// 如果剩余的數據 < 最大處理能力, 就按照剩余的個數來加密數據
buffer = cipher.doFinal(data, offset, total - offset);
// 偏移量設置為總數據長度, 這樣可以跳出循環
offset = total;
}
// 向輸出流寫入數據
baos.write(buffer);
}
}
}
加密算法的安全級別(Security Level of Cryptographic Algorithms):
PBE是一種基于口令的加密算法,使用口令代替其他對稱加密算法中的密鑰,其特點在于口令由用戶自己掌管,不借助任何物理媒體;采用隨機數(這里我們叫做鹽)雜湊多重加密等方法保證數據的安全性。
PBE算法是對稱加密算法的綜合算法,常見算法PBEWithMD5AndDES,使用MD5和DES算法構建了PBE算法。將鹽附加在口令上,通過消息摘要算法經過迭代獲得構建密鑰的基本材料,構建密鑰后使用對稱加密算法進行加密解密。
算法/密鑰長度/默認密鑰長度:
(1)PBEWithMD5AndDES/56/56
(2)PBEWithMD5AndTripleDES/112,168/168
(3)PBEWithSHA1AndDESede/112,168/168
(4)PBEWithSHA1AndRC2_40/40 to 1024/128
工作模式:CBC
填充方式:PKCS5Padding
示例代碼:
import java.security.Key;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class PBEUtil {
public static final String ALGORITHM = "PBEWITHMD5andDES";
public static final int ITERATION_COUNT = 100;
public static byte[] initSalt() throws Exception{
//實例化安全隨機數
SecureRandom random = new SecureRandom();
return random.generateSeed(8);
}
/***
* 轉換密鑰
* @param password 密碼
* @return 密鑰
* @throws Exception
*/
private static Key toKey(String password) throws Exception{
//密鑰材料
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
//實例化
SecretKeyFactory factory = SecretKeyFactory.getInstance(ALGORITHM);
//生成密鑰
return factory.generateSecret(keySpec);
}
/***
* 加密
* @param data 待加密數據
* @param password 密鑰
* @param salt
* @return
* @throws Exception
*/
public static byte[] encrypt(byte[] data, String password, byte[] salt) throws Exception{
//轉換密鑰
Key key = toKey(password);
//實例化PBE參數材料
PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
//實例化
Cipher cipher = Cipher.getInstance(ALGORITHM);
//初始化
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
return cipher.doFinal(data);
}
/***
* 解密
* @param data 待解密數據
* @param password 密鑰
* @param salt
* @return
* @throws Exception
*/
public static byte[] decrypt(byte[] data, String password, byte[] salt) throws Exception{
//轉換密鑰
Key key = toKey(password);
//實例化PBE參數材料
PBEParameterSpec spec = new PBEParameterSpec(salt, ITERATION_COUNT);
//實例化
Cipher cipher = Cipher.getInstance(ALGORITHM);
//初始化
cipher.init(Cipher.DECRYPT_MODE, key, spec);
//執行操作
return cipher.doFinal(data);
}
private static String showByteArray(byte[] data) {
if(null == data) {
return null;
}
StringBuilder sb = new StringBuilder();
for(byte b : data) {
sb.append(b).append(",");
}
sb.deleteCharAt(sb.length()-1);
sb.append("");
return sb.toString();
}
public static void main(String[] args) throws Exception{
byte[] salt = initSalt();
System.out.println("salt:"+showByteArray(salt));
String password = "1111";
System.out.println("口令:"+password);
String data = "PBE數據";
System.out.println("加密前數據:String:"+data);
System.out.println("加密前數據:byte[]:"+showByteArray(data.getBytes()));
byte[] encryptData = encrypt(data.getBytes(), password, salt);
System.out.println("加密后數據:byte[]:"+showByteArray(encryptData));
byte[] decryptData = decrypt(encryptData, password, salt);
System.out.println("解密后數據: byte[]:"+showByteArray(decryptData));
System.out.println("解密后數據: string:"+new String(decryptData));
}
}
0基礎 0學費 15天面授
有基礎 直達就業
業余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習