Java中常用的加密方式(附多個工具類)

一、Java常用加密方式

Base64加密演算法(編碼方式)

MD5加密(訊息摘要演算法,驗證資訊完整性)

對稱加密演算法

非對稱加密演算法

數字簽名演算法

數字證書

二、分類

按加密演算法是否需要key被分為兩類:

不基於key的有: Base64演算法、MD5

基於key的有: 對稱加密演算法、非對稱加密演算法、數字簽名演算法、數字證書、HMAC、RC4(對稱加密)

按加密演算法是否可逆被分為兩類:

單向加密演算法(不可解密):MD5、SHA、HMAC

非單項加密演算法(可解密):BASE64、對稱加密演算法、非對稱加密演算法、數字簽名演算法、數字證書

三、演算法介紹

1。對稱加密

對稱加密是最快速、最簡單的一種加密方式, 加密(encryption)與解密(decryption)用的是同樣的金鑰(secret key) 。對稱加密有很多種演算法,由於它效率很高,所以被廣泛使用在很多加密協議的核心當中。

對稱加密通常使用的是相對較小的金鑰,一般小於256 bit。因為金鑰越大,加密越強,但加密與解密的過程越慢。如果你只用1 bit來做這個金鑰,那駭客們可以先試著用0來解密,不行的話就再用1解;但如果你的金鑰有1 MB大,駭客們可能永遠也無法破解,但加密和解密的過程要花費很長的時間。金鑰的大小既要照顧到安全性,也要照顧到效率,是一個trade-off。

DES (Data Encryption Standard)和 TripleDES 是對稱加密的兩種實現。

DES和TripleDES基本演算法一致,只是TripleDES演算法提供的key位數更多,加密可靠性更高。

DES使用的金鑰key為8位元組,初始向量IV也是8位元組。

TripleDES使用24位元組的key,初始向量IV也是8位元組。

兩種演算法都是以8位元組為一個塊進行加密,一個數據塊一個數據塊的加密,一個8位元組的明文加密後的密文也是8位元組。如果明文長度不為8位元組的整數倍,新增值為0的位元組湊滿8位元組整數倍。所以加密後的密文長度一定為8位元組的整數倍

下面舉個例子:

import java。security。InvalidKeyException;import java。security。Key;import java。security。NoSuchAlgorithmException;import java。security。SecureRandom;import java。security。spec。InvalidKeySpecException; import javax。crypto。Cipher;import javax。crypto。SecretKey;import javax。crypto。SecretKeyFactory;import javax。crypto。spec。DESKeySpec; import org。apache。commons。codec。binary。Base64; public class DESDemo { // 演算法名稱 public static final String KEY_ALGORITHM = “DES”; // 演算法名稱/加密模式/填充方式 // DES共有四種工作模式——>>ECB:電子密碼本模式、CBC:加密分組連結模式、CFB:加密反饋模式、OFB:輸出反饋模式 public static final String CIPHER_ALGORITHM = “DES/ECB/NoPadding”; /** * * 生成金鑰key物件 * * @param KeyStr * 金鑰字串 * @return 金鑰物件 * @throws InvalidKeyException * @throws NoSuchAlgorithmException * @throws InvalidKeySpecException * @throws Exception */ private static SecretKey keyGenerator(String keyStr) throws Exception { byte input[] = HexString2Bytes(keyStr); DESKeySpec desKey = new DESKeySpec(input); // 建立一個密匙工廠,然後用它把DESKeySpec轉換成 SecretKeyFactory keyFactory = SecretKeyFactory。getInstance(“DES”); SecretKey securekey = keyFactory。generateSecret(desKey); return securekey; } private static int parse(char c) { if (c >= ‘a’) return (c - ‘a’ + 10) & 0x0f; if (c >= ‘A’) return (c - ‘A’ + 10) & 0x0f; return (c - ‘0’) & 0x0f; } // 從十六進位制字串到位元組陣列轉換 public static byte[] HexString2Bytes(String hexstr) { byte[] b = new byte[hexstr。length() / 2]; int j = 0; for (int i = 0; i < b。length; i++) { char c0 = hexstr。charAt(j++); char c1 = hexstr。charAt(j++); b[i] = (byte) ((parse(c0) << 4) | parse(c1)); } return b; } /** * 加密資料 * * @param data * 待加密資料 * @param key * 金鑰 * @return 加密後的資料 */ public static String encrypt(String data, String key) throws Exception { Key deskey = keyGenerator(key); // 例項化Cipher物件,它用於完成實際的加密操作 Cipher cipher = Cipher。getInstance(CIPHER_ALGORITHM); SecureRandom random = new SecureRandom(); // 初始化Cipher物件,設定為加密模式 cipher。init(Cipher。ENCRYPT_MODE, deskey, random); byte[] results = cipher。doFinal(data。getBytes()); // 該部分是為了與加解密線上測試網站(http://tripledes。online-domain-tools。com/)的十六進位制結果進行核對 for (int i = 0; i < results。length; i++) { System。out。print(results[i] + “ ”); } System。out。println(); // 執行加密操作。加密後的結果通常都會用Base64編碼進行傳輸 return Base64。encodeBase64String(results); } /** * 解密資料 * * @param data * 待解密資料 * @param key * 金鑰 * @return 解密後的資料 */ public static String decrypt(String data, String key) throws Exception { Key deskey = keyGenerator(key); Cipher cipher = Cipher。getInstance(CIPHER_ALGORITHM); // 初始化Cipher物件,設定為解密模式 cipher。init(Cipher。DECRYPT_MODE, deskey); // 執行解密操作 return new String(cipher。doFinal(Base64。decodeBase64(data))); } public static void main(String[] args) throws Exception { String source = “helloittx”; System。out。println(“原文: ” + source); String key = “A1B2C3D4E5F60708”; String encryptData = encrypt(source, key); System。out。println(“加密後: ” + encryptData); String decryptData = decrypt(encryptData, key); System。out。println(“解密後: ” + decryptData); }}

2。非對稱加密

非對稱加密為資料的加密與解密提供了一個非常安全的方法,它使用了一對金鑰,公鑰(public key)和私鑰(private key)。私鑰只能由一方安全保管,不能外洩,而公鑰則可以發給任何請求它的人。非對稱加密使用這對金鑰中的一個進行加密,而解密則需要另一個金鑰。比如,你向銀行請求公鑰,銀行將公鑰發給你,你使用公鑰對訊息加密,那麼只有私鑰的持有人–銀行才能對你的訊息解密。與對稱加密不同的是,銀行不需要將私鑰透過網路傳送出去,因此安全性大大提高。

目前最常用的非對稱加密演算法是RSA演算法,是Rivest, Shamir, 和Adleman於1978年發明,他們那時都是在MIT。請看下面的例子:

import java。io。FileInputStream;import java。io。FileOutputStream;import java。io。ObjectInputStream;import java。io。ObjectOutputStream;import java。math。BigInteger;import java。security。Key;import java。security。KeyFactory;import java。security。KeyPair;import java。security。KeyPairGenerator;import java。security。SecureRandom;import java。security。spec。RSAPrivateCrtKeySpec;import java。security。spec。RSAPublicKeySpec; import javax。crypto。Cipher; import com。lxh。rsatest。HexUtil; import Decoder。BASE64Decoder;import Decoder。BASE64Encoder; public class RSAEncrypt { /** 指定加密演算法為DESede */ private static String ALGORITHM = “RSA”; /** 指定key的大小 */ private static int KEYSIZE = 1024; /** 指定公鑰存放檔案 */ private static String PUBLIC_KEY_FILE = “public。keystore”; /** 指定私鑰存放檔案 */ private static String PRIVATE_KEY_FILE = “private。keystore”; /** * 生成金鑰對 */ private static void generateKeyPair() throws Exception { /** RSA演算法要求有一個可信任的隨機數源 */ SecureRandom sr = new SecureRandom(); /** 為RSA演算法建立一個KeyPairGenerator物件 */ KeyPairGenerator kpg = KeyPairGenerator。getInstance(ALGORITHM); /** 利用上面的隨機資料來源初始化這個KeyPairGenerator物件 */ kpg。initialize(KEYSIZE, sr); /** 生成密匙對 */ KeyPair kp = kpg。generateKeyPair(); /** 得到公鑰 */ Key publicKey = kp。getPublic(); /** 得到私鑰 */ Key privateKey = kp。getPrivate(); /** 用物件流將生成的金鑰寫入檔案 */ ObjectOutputStream oos1 = new ObjectOutputStream(new FileOutputStream(PUBLIC_KEY_FILE)); ObjectOutputStream oos2 = new ObjectOutputStream(new FileOutputStream(PRIVATE_KEY_FILE)); oos1。writeObject(publicKey); oos2。writeObject(privateKey); /** 清空快取,關閉檔案輸出流 */ oos1。close(); oos2。close(); } /** * 生成金鑰對字串 */ private static void generateKeyPairString() throws Exception { /** RSA演算法要求有一個可信任的隨機數源 */ SecureRandom sr = new SecureRandom(); /** 為RSA演算法建立一個KeyPairGenerator物件 */ KeyPairGenerator kpg = KeyPairGenerator。getInstance(ALGORITHM); /** 利用上面的隨機資料來源初始化這個KeyPairGenerator物件 */ kpg。initialize(KEYSIZE, sr); /** 生成密匙對 */ KeyPair kp = kpg。generateKeyPair(); /** 得到公鑰 */ Key publicKey = kp。getPublic(); /** 得到私鑰 */ Key privateKey = kp。getPrivate(); /** 用字串將生成的金鑰寫入檔案 */ String algorithm = publicKey。getAlgorithm(); // 獲取演算法 KeyFactory keyFact = KeyFactory。getInstance(algorithm); BigInteger prime = null; BigInteger exponent = null; RSAPublicKeySpec keySpec = (RSAPublicKeySpec) keyFact。getKeySpec(publicKey, RSAPublicKeySpec。class); prime = keySpec。getModulus(); exponent = keySpec。getPublicExponent(); System。out。println(“公鑰模量:” + HexUtil。bytes2Hex(prime。toByteArray())); System。out。println(“公鑰指數:” + HexUtil。bytes2Hex(exponent。toByteArray())); System。out。println(privateKey。getAlgorithm()); RSAPrivateCrtKeySpec privateKeySpec = (RSAPrivateCrtKeySpec) keyFact。getKeySpec(privateKey, RSAPrivateCrtKeySpec。class); BigInteger privateModulus = privateKeySpec。getModulus(); BigInteger privateExponent = privateKeySpec。getPrivateExponent(); System。out。println(“私鑰模量:” + HexUtil。bytes2Hex(privateModulus。toByteArray())); System。out。println(“私鑰指數:” + HexUtil。bytes2Hex(privateExponent。toByteArray())); } /** * 加密方法 source: 源資料 */ public static String encrypt(String source) throws Exception { generateKeyPair(); /** 將檔案中的公鑰物件讀出 */ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE)); Key key = (Key) ois。readObject(); ois。close(); String algorithm = key。getAlgorithm(); // 獲取演算法 KeyFactory keyFact = KeyFactory。getInstance(algorithm); BigInteger prime = null; BigInteger exponent = null; if (“RSA”。equals(algorithm)) { // 如果是RSA加密 RSAPublicKeySpec keySpec = (RSAPublicKeySpec) keyFact。getKeySpec(key, RSAPublicKeySpec。class); prime = keySpec。getModulus(); exponent = keySpec。getPublicExponent(); // System。out。println(“公鑰模量:” + HexUtil。bytes2Hex(prime。toByteArray()));// System。out。println(“公鑰指數:” + HexUtil。bytes2Hex(exponent。toByteArray())); } /** 得到Cipher物件來實現對源資料的RSA加密 */ Cipher cipher = Cipher。getInstance(ALGORITHM); cipher。init(Cipher。ENCRYPT_MODE, key); byte[] b = source。getBytes(); /** 執行加密操作 */ byte[] b1 = cipher。doFinal(b); BASE64Encoder encoder = new BASE64Encoder(); return encoder。encode(b1); } /** * 解密演算法 cryptograph:密文 */ public static String decrypt(String cryptograph) throws Exception { /** 將檔案中的私鑰物件讀出 */ ObjectInputStream ois = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE)); Key key = (Key) ois。readObject(); String algorithm = key。getAlgorithm(); // 獲取演算法 KeyFactory keyFact = KeyFactory。getInstance(algorithm); RSAPrivateCrtKeySpec privateKeySpec = (RSAPrivateCrtKeySpec) keyFact。getKeySpec(key, RSAPrivateCrtKeySpec。class); BigInteger privateModulus = privateKeySpec。getModulus(); BigInteger privateExponent = privateKeySpec。getPrivateExponent(); // System。out。println(“私鑰模量:” + HexUtil。bytes2Hex(privateModulus。toByteArray()));// System。out。println(“私鑰指數:” + HexUtil。bytes2Hex(privateExponent。toByteArray())); /** 得到Cipher物件對已用公鑰加密的資料進行RSA解密 */ Cipher cipher = Cipher。getInstance(ALGORITHM); cipher。init(Cipher。DECRYPT_MODE, key); BASE64Decoder decoder = new BASE64Decoder(); byte[] b1 = decoder。decodeBuffer(cryptograph); /** 執行解密操作 */ byte[] b = cipher。doFinal(b1); return new String(b); } public static void main(String[] args) throws Exception { generateKeyPair(); //生成檔案形式公鑰和私鑰 //generateKeyPairString();//生成字串形式公鑰和私鑰 String source = “非對稱加密RSA”;// 要加密的字串 String cryptograph = encrypt(source);// 生成的密文 String hexCrypt = HexUtil。bytes2Hex(cryptograph。getBytes(), false); System。out。println(“生成的密文——->” + hexCrypt); String target = decrypt(HexUtil。hex2String(hexCrypt));// 解密密文 System。out。println(“解密密文——->” + target); }}

雖然非對稱加密很安全,但是和對稱加密比起來,它非常的慢,所以我們還是要用對稱加密來傳送訊息,但對稱加密所使用的金鑰我們可以透過非對稱加密的方式傳送出去。

(1) 對稱加密加密與解密使用的是同樣的金鑰,所以速度快,但由於需要將金鑰在網路傳輸,所以安全性不高。

(2) 非對稱加密使用了一對金鑰,公鑰與私鑰,所以安全性高,但加密與解密速度慢。

(3) 解決的辦法是將對稱加密的金鑰使用非對稱加密的公鑰進行加密,然後傳送出去,接收方使用私鑰進行解密得到對稱加密的金鑰,然後雙方可以使用對稱加密來進行溝通。

3。Base64編碼

Base 64 Encoding有什麼用?舉個簡單的例子,你使用SMTP協議 (Simple Mail Transfer Protocol 簡單郵件傳輸協議)來發送郵件。因為這個協議是基於文字的協議,所以如果郵件中包含一幅圖片,我們知道圖片的儲存格式是二進位制資料(binary data),而非文字格式,我們必須將二進位制的資料編碼成文字格式,這時候Base 64 Encoding就派上用場了。

public void testJDKBase64(){ String encoderStr = java。util。Base64。getEncoder()。encodeToString(s。getBytes()); System。out。println(“encode :”+encoderStr); String decodeStr = new String(java。util。Base64。getDecoder()。decode(encoderStr)); System。out。println(“decodeStr :”+decodeStr);} public void testCodecBase64(){ String encoderStr = org。apache。commons。codec。binary。Base64。encodeBase64String(s。getBytes()); System。out。println(“encode :”+encoderStr); String decodeStr = new String(org。apache。commons。codec。binary。Base64。decodeBase64(encoderStr)); System。out。println(“decodeStr :”+decodeStr);}

附工具類

package com。hl。bluetooth。util;import org。springframework。boot。system。ApplicationHome;import org。springframework。stereotype。Component;import org。springframework。web。multipart。MultipartFile;import sun。misc。BASE64Decoder;import sun。misc。BASE64Encoder;import java。io。*;import java。util。Objects;/** * @DateL 2021/11/16 15:09 * @ClassName: FileUtils **/@Componentpublic class FileUtils { public static File multipartFileToFile(MultipartFile multipartFile) { File file = new File(Objects。requireNonNull(multipartFile。getOriginalFilename())); try { InputStream ins = null; ins = multipartFile。getInputStream(); OutputStream os = new FileOutputStream(file); int bytesRead = 0; byte[] buffer = new byte[8192]; while ((bytesRead = ins。read(buffer, 0, 8192)) != -1) { os。write(buffer, 0, bytesRead); } os。close(); ins。close(); } catch (Exception e) { e。printStackTrace(); } return file; } /** * 圖片轉化成base64字串 * */ public static String getImageStr(String imgPath) { InputStream in = null; byte[] data = null; String encode = null; // 對位元組陣列Base64編碼 BASE64Encoder encoder = new BASE64Encoder(); try { // 讀取圖片位元組陣列 in = new FileInputStream(imgPath); data = new byte[in。available()]; in。read(data); encode = encoder。encode(data); } catch (IOException e) { e。printStackTrace(); } finally { try { in。close(); } catch (IOException e) { e。printStackTrace(); } } return encode; } /** * base64字串轉化成圖片 * * @param imgData 圖片編碼 */ public static String generateImage(String imgData, String fileName) { if (imgData == null) { // 影象資料為空 return “null”; } ApplicationHome applicationHome = new ApplicationHome(FileUtils。class); File source = applicationHome。getSource(); String dirPath = source。getParentFile()。toString() + “/upload”; BASE64Decoder decoder = new BASE64Decoder(); File dir = new File(dirPath); if (!dir。exists()){ dir。mkdirs(); } File file = new File(dirPath+“/”+fileName); if (file。exists()){ file。delete(); } try { // Base64解碼 byte[] b = decoder。decodeBuffer(imgData); for (int i = 0; i < b。length; ++i) { // 調整異常資料 if (b[i] < 0) { b[i] += 256; } } OutputStream out = new FileOutputStream(dirPath+“\\”+fileName); out。write(b); out。flush(); out。close(); return dirPath+“\\”+fileName; } catch (Exception e) { e。printStackTrace(); return “null”; } }}

4。MD5加密

Message Digest Algorithm MD5(中文名為訊息摘要演算法第五版)為計算機安全領域廣泛使用的一種雜湊函式,用以提供訊息的完整性保護。該演算法的檔案號為RFC 1321(R。Rivest,MIT Laboratory for Computer Science and RSA Data Security Inc。 April 1992)。

MD5的全稱是Message-Digest Algorithm 5(資訊-摘要演算法),在90年代初由MIT Laboratory for Computer Science和RSA Data Security Inc的Ronald L。 Rivest開發出來,經MD2、MD3和MD4發展而來。

MD5用於確保資訊傳輸完整一致。是計算機廣泛使用的雜湊演算法之一(又譯摘要演算法、雜湊演算法),主流程式語言普遍已有MD5實現。將資料(如漢字)運算為另一固定長度值,是雜湊演算法的基礎原理,MD5的前身有MD2、MD3和MD4。

MD5的作用是讓大容量資訊在用數字簽名軟體簽署私人金鑰前被”壓縮”成一種保密的格式(就是把一個任意長度的位元組串變換成一定長的十六進位制數字串)。

import java。security。MessageDigest;import java。security。NoSuchAlgorithmException; /** * Java訊息摘要演算法 MD5 工具類,其實其他摘要演算法的實現也類似 */public class MD5Util { /** * 對文字執行 md5 摘要加密, 此演算法與 mysql,JavaScript生成的md5摘要進行過一致性對比。 * @param plainText * @return 返回值中的字母為小寫 */ public static String md5(String plainText) { if (null == plainText) { plainText = “”; } String MD5Str = “”; try { // JDK 6 支援以下6種訊息摘要演算法,不區分大小寫 // md5,sha(sha-1),md2,sha-256,sha-384,sha-512 MessageDigest md = MessageDigest。getInstance(“MD5”); md。update(plainText。getBytes()); byte b[] = md。digest(); int i; StringBuilder builder = new StringBuilder(32); for (int offset = 0; offset < b。length; offset++) { i = b[offset]; if (i < 0) i += 256; if (i < 16) builder。append(“0”); builder。append(Integer。toHexString(i)); } MD5Str = builder。toString(); // LogUtil。println(“result: ” + buf。toString());// 32位的加密 } catch (NoSuchAlgorithmException e) { e。printStackTrace(); } return MD5Str; } // 一個簡版測試 public static void main(String[] args) { String m1 = md5(“1”); String m2 = md5(m1); /* 輸出為 * m1=c4ca4238a0b923820dcc509a6f75849b * m2=28c8edde3d61a0411511d3b1866f0636 */ System。out。println(“m1=”+m1); System。out。println(“m2=”+m2); }}

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

5。數字簽名演算法

簽名:就有安全性,抗否認性

數字簽名:帶有金鑰(公鑰,私鑰)的訊息摘要演算法

作用:

1。 驗證資料的完整性

2。 認證資料來源

3。 抗否認

數字簽名遵循:私鑰簽名,公鑰驗證

常用的數字簽名演算法:RSA,DSA,ECDSA

RSA介紹:

是經典演算法,是目前為止使用最廣泛的數字簽名演算法。

RSA數字簽名演算法的金鑰實現與RSA的加密演算法是一樣的,演算法的名稱都叫RSA。金鑰的產生和轉換都是一樣的。

RSA數字簽名演算法主要包括MD和SHA兩類。

import java。security。KeyFactory;import java。security。KeyPair;import java。security。KeyPairGenerator;import java。security。PrivateKey;import java。security。PublicKey;import java。security。Signature;import java。security。interfaces。RSAPrivateKey;import java。security。interfaces。RSAPublicKey;import java。security。spec。PKCS8EncodedKeySpec;import java。security。spec。X509EncodedKeySpec; import org。apache。commons。codec。binary。Hex; public class RSATest { public static final String src = “hello world”; public static void main(String[] args) { jdkRSA(); } /** * 說明: 用java的jdk裡面相關方法實現rsa的簽名及簽名驗證 */ public static void jdkRSA() { try { // 1。初始化金鑰 KeyPairGenerator keyPairGenerator = KeyPairGenerator 。getInstance(“RSA”); //設定KEY的長度 keyPairGenerator。initialize(512); KeyPair keyPair = keyPairGenerator。generateKeyPair(); //得到公鑰 RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair。getPublic(); //得到私鑰 RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair。getPrivate(); // 2。進行簽名 //用私鑰進行簽名 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec( rsaPrivateKey。getEncoded()); KeyFactory keyFactory = KeyFactory。getInstance(“RSA”); //構造一個privateKey PrivateKey privateKey = keyFactory 。generatePrivate(pkcs8EncodedKeySpec); //宣告簽名的物件 Signature signature = Signature。getInstance(“MD5withRSA”); signature。initSign(privateKey); signature。update(src。getBytes()); //進行簽名 byte[] result = signature。sign(); System。out。println(“jdk rsa sign:” + Hex。encodeHexString(result)); // 3。驗證簽名 //用公鑰進行驗證簽名 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec( rsaPublicKey。getEncoded()); keyFactory = KeyFactory。getInstance(“RSA”); //構造一個publicKey PublicKey publicKey = keyFactory。generatePublic(x509EncodedKeySpec); //宣告簽名物件 signature = Signature。getInstance(“MD5withRSA”); signature。initVerify(publicKey); signature。update(src。getBytes()); //驗證簽名 boolean bool = signature。verify(result); System。out。println(“jdk rsa verify:” + bool); } catch (Exception e) { System。out。println(e。toString()); } } }

四、應用場景

Base64應用場景:圖片轉碼(應用於郵件,img標籤,http加密)

MD5應用場景:密碼加密、imei加密、檔案校驗

非對稱加密:電商訂單付款、銀行相關業務

五、附多個工具類

AES

package com。hl。bluetooth。util;import org。apache。commons。lang3。StringUtils;import org。apache。tomcat。util。codec。binary。Base64;import javax。crypto。Cipher;import javax。crypto。spec。IvParameterSpec;import javax。crypto。spec。SecretKeySpec;public class AesEncryptUtil { //使用AES-128-CBC加密模式,key需要為16位,key和iv可以相同! private final static String KEY = “ABCDEF1234432100”; private final static String IV = “43211234DCAB6789”; /** * 加密方法 * @param data 要加密的資料 * @param key 加密key * @param iv 加密iv * @return 加密的結果 * @throws Exception */ public static String encrypt(String data, String key, String iv) throws Exception { try { Cipher cipher = Cipher。getInstance(“AES/CBC/NoPadding”);//“演算法/模式/補碼方式”NoPadding PkcsPadding int blockSize = cipher。getBlockSize(); byte[] dataBytes = data。getBytes(); int plaintextLength = dataBytes。length; if (plaintextLength % blockSize != 0) { plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize)); } byte[] plaintext = new byte[plaintextLength]; System。arraycopy(dataBytes, 0, plaintext, 0, dataBytes。length); SecretKeySpec keyspec = new SecretKeySpec(key。getBytes(), “AES”); IvParameterSpec ivspec = new IvParameterSpec(iv。getBytes()); cipher。init(Cipher。ENCRYPT_MODE, keyspec, ivspec); byte[] encrypted = cipher。doFinal(plaintext); return new Base64()。encodeToString(encrypted); } catch (Exception e) { e。printStackTrace(); return null; } } /** * 解密方法 * @param data 要解密的資料 * @param key 解密key * @param iv 解密iv * @return 解密的結果 * @throws Exception */ public static String desEncrypt(String data, String key, String iv) throws Exception { try {// byte[] encrypted1 = new Base64()。decode(data); byte[] encrypted1 = parseHexStr2Byte(data);// Cipher cipher = Cipher。getInstance(“AES/CBC/NoPadding”); Cipher cipher = Cipher。getInstance(“AES/CBC/PKCS5Padding”); SecretKeySpec keyspec = new SecretKeySpec(key。getBytes(), “AES”); IvParameterSpec ivspec = new IvParameterSpec(iv。getBytes()); cipher。init(Cipher。DECRYPT_MODE, keyspec, ivspec); byte[] original = cipher。doFinal(encrypted1); String originalString = new String(original); return originalString; } catch (Exception e) { e。printStackTrace(); return null; } } /** * 使用預設的key和iv加密 * @param data * @return * @throws Exception */ public static String encrypt(String data) throws Exception { return encrypt(data, KEY, IV); } /** * 使用預設的key和iv解密 * @param data * @return * @throws Exception */ public static String desEncrypt(String data) throws Exception { if (StringUtils。isEmpty(data)) { return null; } return desEncrypt(data, KEY, IV); } /** * @Author wdc * @Description 16進位制轉byte陣列 * @Date 2021/4/19 11:14 * @Param [hexStr] * @return byte[] **/ public static byte[] parseHexStr2Byte(String hexStr) { if (hexStr。length() < 1) return null; byte[] result = new byte[hexStr。length()/2]; for (int i = 0;i< hexStr。length()/2; i++) { int high = Integer。parseInt(hexStr。substring(i*2, i*2+1), 16); int low = Integer。parseInt(hexStr。substring(i*2+1, i*2+2), 16); result[i] = (byte) (high * 16 + low); } return result; } public static void main(String[] args) {// String test = “{‘admin’,‘admin’}”;//// String test =new String(test1。getBytes(),“UTF-8”);// String data = null;// data = AesEncryptUtil。encrypt(test);// System。out。println(“資料:”+test);// System。out。println(“加密:”+data);// String jiemi = AesEncryptUtil。desEncrypt(data);// System。out。println(“解密:”+jiemi); }}

base64

package com。sgitg。util;import java。io。UnsupportedEncodingException;import org。springframework。util。Base64Utils;public class Base64Util { /** * 解碼base64編碼的字串 * * @param source * @return * @throws UnsupportedEncodingException */ public static String decodeFromString(String source) { String str = “”; try { byte[] bt = Base64Utils。decodeFromString(source); str = new String(bt, “utf-8”); } catch (UnsupportedEncodingException e) { e。printStackTrace(); // To change body of catch statement use File | // Settings | File Templates。 } return str; } /** * 對字串進行base64編碼 * * @param source * @return * @throws UnsupportedEncodingException */ public static String encodeToString(String source) { byte[] bt = new byte[0]; try { bt = source。getBytes(“utf-8”); } catch (UnsupportedEncodingException e) { e。printStackTrace(); // To change body of catch statement use File | // Settings | File Templates。 } return Base64Utils。encodeToString(bt); }}

EncryptUtils (編碼集合)

* 1、Base64編碼* 1、AES、DES可逆演算法* 2、md5,Hex,Sha不可逆演算法加密

package com。sgitg。util;import org。apache。commons。codec。digest。DigestUtils;import javax。crypto。Cipher;import javax。crypto。KeyGenerator;import javax。crypto。SecretKey;import javax。crypto。spec。SecretKeySpec;import java。io。File;import java。io。FileInputStream;import java。io。FileNotFoundException;import java。io。IOException;import java。nio。MappedByteBuffer;import java。nio。channels。FileChannel;import java。security。MessageDigest;import java。security。NoSuchAlgorithmException;import java。security。SecureRandom;import java。util。Base64;import java。util。zip。CRC32;/** * 資料加密 * 繼承org。apache。commons。codec。digest。DigestUtils * 1、Base64編碼 * 1、AES、DES可逆演算法 * 2、md5,Hex,Sha不可逆演算法加密 * * @author liuyadu */public class EncryptUtils extends DigestUtils { /** * 計算大檔案 md5獲取getMD5(); SHA1獲取getSha1() CRC32獲取 getCRC32() */ private static char[] hexDigits = {‘0’, ‘1’, ‘2’, ‘3’, ‘4’, ‘5’, ‘6’, ‘7’, ‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’}; // 測試 public static void main(String[] args) { String en = encryptDES(“hahahaha”, “yaer”); String de = decryptDES(“kzWPLLyAsDeBr84lL2COsA==”, “yaer”); System。out。println(de); System。out。println(en); en = encryptAES(“hahahaha”, “yaer”); de = decryptAES(“FBC82B89BAA1FBBDF3AE086A09D57E7C”, “yaer”); System。out。println(de); System。out。println(en); } /** * AES加密(可逆) * * @param plainText 明文 * @param privateKey 金鑰 * @return * @throws NoSuchAlgorithmException */ public static String encryptAES(String plainText, String privateKey) { try { KeyGenerator kgen = KeyGenerator。getInstance(“AES”); SecureRandom random = SecureRandom。getInstance(“SHA1PRNG”); random。setSeed(privateKey。getBytes()); kgen。init(128, random); SecretKey secretKey = kgen。generateKey(); byte[] enCodeFormat = secretKey。getEncoded(); SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, “AES”); Cipher cipher = Cipher。getInstance(“AES”); byte[] byteContent = plainText。getBytes(“utf-8”); cipher。init(Cipher。ENCRYPT_MODE, secretKeySpec); byte[] byteRresult = cipher。doFinal(byteContent); String sb = new String(“”); for (int i = 0; i < byteRresult。length; i++) { String hex = Integer。toHexString(byteRresult[i] & 0xFF); if (hex。length() == 1) { hex = ‘0’ + hex; } sb = sb。concat(hex。toUpperCase()); } return sb; } catch (Exception e) { return null; } } /** * AES解密 * * @param cipherText 密文 * @param privateKey 金鑰 * @return * @throws Exception */ public static String decryptAES(String cipherText, String privateKey) { try { if (cipherText。length() < 1) { return null; } byte[] byteRresult = new byte[cipherText。length() / 2]; for (int i = 0; i < cipherText。length() / 2; i++) { int high = Integer。parseInt(cipherText。substring(i * 2, i * 2 + 1), 16); int low = Integer。parseInt(cipherText。substring(i * 2 + 1, i * 2 + 2), 16); byteRresult[i] = (byte) (high * 16 + low); } KeyGenerator kgen = KeyGenerator。getInstance(“AES”); SecureRandom random = SecureRandom。getInstance(“SHA1PRNG”); random。setSeed(privateKey。getBytes()); kgen。init(128, random); SecretKey secretKey = kgen。generateKey(); byte[] enCodeFormat = secretKey。getEncoded(); SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, “AES”); Cipher cipher = Cipher。getInstance(“AES”); cipher。init(Cipher。DECRYPT_MODE, secretKeySpec); byte[] result = cipher。doFinal(byteRresult); return new String(result); } catch (Exception e) { return null; } } /** * 加密DES(可逆) * * @param plainText 明文 * @param privateKey 金鑰 * @return */ public static String encryptDES(String plainText, String privateKey) { try { KeyGenerator keygen = KeyGenerator。getInstance(“DES”); SecureRandom secureRandom = SecureRandom。getInstance(“SHA1PRNG”); secureRandom。setSeed(privateKey。getBytes()); keygen。init(56, secureRandom); SecretKey secretKey = keygen。generateKey(); Cipher cipher = Cipher。getInstance(“DES/ECB/PKCS5Padding”); cipher。init(Cipher。ENCRYPT_MODE, secretKey); byte[] cipherBytes = cipher。doFinal(plainText。getBytes(“utf-8”)); byte[] plainTextBytes = Base64。getEncoder()。encode(cipherBytes); return new String(plainTextBytes, “utf-8”); } catch (Exception e) { e。printStackTrace(); return null; } } /** * 解密DES * * @param cipherText 密文 * @param privateKey 金鑰 * @return */ public static String decryptDES(String cipherText, String privateKey) { try { KeyGenerator keygen = KeyGenerator。getInstance(“DES”); SecureRandom secureRandom = SecureRandom。getInstance(“SHA1PRNG”); secureRandom。setSeed(privateKey。getBytes()); keygen。init(56, secureRandom); SecretKey secretKey = keygen。generateKey(); Cipher cipher = Cipher。getInstance(“DES/ECB/PKCS5Padding”); cipher。init(Cipher。DECRYPT_MODE, secretKey); byte[] cipherTextBytes = Base64。getDecoder()。decode(cipherText。getBytes(“utf-8”)); byte[] cipherBytes = cipher。doFinal(cipherTextBytes); return new String(cipherBytes, “utf-8”); } catch (Exception e) { e。printStackTrace(); return null; } } /** * 獲取檔案md5值 * * @return md5串 */ public static String md5(File file) { try { //encrypt MessageDigest messagedigest = MessageDigest。getInstance(“MD5”); FileInputStream in = new FileInputStream(file); FileChannel ch = in。getChannel(); MappedByteBuffer byteBuffer = ch。map(FileChannel。MapMode。READ_ONLY, 0, file。length()); messagedigest。update(byteBuffer); return bufferToHex(messagedigest。digest()); } catch (Exception e) { return null; } } /*** * 獲取檔案SHA1值 * * @return String 適用於上G大的檔案 */ public static String sha1(File file) { try { MessageDigest messagedigest = MessageDigest。getInstance(“SHA-1”); FileInputStream in = new FileInputStream(file); FileChannel ch = in。getChannel(); MappedByteBuffer byteBuffer = ch。map(FileChannel。MapMode。READ_ONLY, 0, file。length()); messagedigest。update(byteBuffer); return bufferToHex(messagedigest。digest()); } catch (Exception e) { return null; } } /** * 獲取檔案SHA256值 * * @return String */ public static String sha256(File file) { try { MessageDigest messagedigest = MessageDigest。getInstance(“SHA-256”); FileInputStream in = new FileInputStream(file); FileChannel ch = in。getChannel(); MappedByteBuffer byteBuffer = ch。map(FileChannel。MapMode。READ_ONLY, 0, file。length()); messagedigest。update(byteBuffer); return bufferToHex(messagedigest。digest()); } catch (Exception e) { return null; } } /** * 獲取檔案CRC32碼 * * @return String */ public static String crc32(File file) { CRC32 crc32 = new CRC32(); // MessageDigest。get FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(file); byte[] buffer = new byte[8192]; int length; while ((length = fileInputStream。read(buffer)) != -1) { crc32。update(buffer, 0, length); } return crc32。getValue() + “”; } catch (FileNotFoundException e) { e。printStackTrace(); return null; } catch (IOException e) { e。printStackTrace(); return null; } finally { try { if (fileInputStream != null) { fileInputStream。close(); } } catch (IOException e) { e。printStackTrace(); } } } /** * 計算二進位制資料 * * @return */ private static String bufferToHex(byte bytes[]) { return bufferToHex(bytes, 0, bytes。length); } private static String bufferToHex(byte bytes[], int m, int n) { StringBuffer stringbuffer = new StringBuffer(2 * n); int k = m + n; for (int l = m; l < k; l++) { appendHexPair(bytes[l], stringbuffer); } return stringbuffer。toString(); } private static void appendHexPair(byte bt, StringBuffer stringbuffer) { char c0 = hexDigits[(bt & 0xf0) >> 4]; char c1 = hexDigits[bt & 0xf]; stringbuffer。append(c0); stringbuffer。append(c1); }}