java?AES加密/解密實現(xiàn)完整代碼(附帶源碼)
1. 項目背景與介紹
在數(shù)據(jù)傳輸和存儲過程中,保護敏感信息的安全性非常關鍵。AES(Advanced Encryption Standard,高級加密標準)是一種廣泛使用的對稱加密算法,具有高效、安全、易于實現(xiàn)等特點。由于 AES 使用同一個密鑰進行加密和解密,因此密鑰的管理非常重要。
本項目將通過 Java 內(nèi)置的加密 API(主要在 javax.crypto 包中提供)實現(xiàn) AES 加密與解密。示例中我們采用 AES/CBC/PKCS5Padding 模式,并使用一個 128 位(16 字節(jié))的密鑰和固定的初始向量(IV)。為了便于演示,本示例使用了固定的 IV,但在實際應用中,建議使用隨機 IV,并將 IV 與密文一起存儲或傳輸。
通過本項目,你將掌握如何使用 Java 進行 AES 加密和解密操作,并了解如何對密鑰和初始向量進行設置、Base64 編碼結(jié)果輸出等知識點。
2. 相關知識
2.1 AES 加密算法
- 對稱加密:AES 算法屬于對稱加密算法,即加密和解密使用相同的密鑰。其優(yōu)點是速度快,適合大數(shù)據(jù)量加密;缺點是密鑰傳輸和管理存在一定風險。
- 加密模式與填充方式:常用的模式有 ECB、CBC、CFB 等,本示例采用 CBC 模式。由于 AES 的塊大小為 16 字節(jié),當明文長度不是 16 字節(jié)的整數(shù)倍時,需要采用填充方式,本示例采用 PKCS5Padding。
- 初始向量(IV):在 CBC 模式下,初始向量用于增加加密隨機性,通常需要隨機生成并與密文一起存儲。但本示例為了簡化演示,使用了固定的 IV(僅供學習參考)。
2.2 Java 加密 API
Java 提供了一整套加密相關的類:
- Cipher:核心加密解密類,用于執(zhí)行加密和解密操作。
- SecretKeySpec:將原始密鑰數(shù)據(jù)封裝為密鑰對象。
- IvParameterSpec:封裝初始向量數(shù)據(jù)。
- Base64:用于將二進制數(shù)據(jù)轉(zhuǎn)換為可讀的字符串格式,便于傳輸和存儲。
3. 項目實現(xiàn)思路
本項目主要分為以下幾個步驟:
準備密鑰和初始向量定義 AES 加密所需的 128 位密鑰和 16 字節(jié)的初始向量(IV)。在實際應用中,這些應由安全隨機數(shù)生成器產(chǎn)生,并妥善管理。
創(chuàng)建 Cipher 對象使用
Cipher.getInstance("AES/CBC/PKCS5Padding")獲取 Cipher 對象,并分別用密鑰和 IV 初始化加密和解密模式。執(zhí)行加密和解密操作
- 加密:將明文字符串轉(zhuǎn)換為字節(jié)數(shù)組,調(diào)用
doFinal()方法獲得密文字節(jié)數(shù)組,再進行 Base64 編碼。 - 解密:將 Base64 解碼后的密文字節(jié)數(shù)組通過
doFinal()方法還原為明文字節(jié)數(shù)組,并轉(zhuǎn)換為字符串。
- 加密:將明文字符串轉(zhuǎn)換為字節(jié)數(shù)組,調(diào)用
整合代碼并測試將上述流程封裝到一個 Java 類中,在主函數(shù)中調(diào)用加密和解密方法,驗證加解密是否正確。
4. 完整代碼實現(xiàn)
下面是一份完整的 Java 代碼示例,實現(xiàn)了 AES 加密與解密功能。代碼中附有詳細中文注釋,便于理解每個步驟的實現(xiàn)細節(jié)。
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.util.Base64;
/**
* AESEncryptionDemo 類演示了如何使用 Java 實現(xiàn) AES 加密和解密。
* 本示例使用 AES/CBC/PKCS5Padding 模式,密鑰和初始向量均為 16 字節(jié)(128 位)。
* 注意:示例中使用固定 IV 僅供學習,實際應用中應使用隨機 IV 并與密文一起傳輸。
*/
public class AESEncryptionDemo {
// AES 密鑰(16 字節(jié)):請確保密鑰足夠隨機和安全
private static final String KEY = "0123456789abcdef";
// 初始向量(IV,16 字節(jié)):實際應用中應隨機生成
private static final String IV = "abcdefghijklmnop";
// 指定加密算法和模式
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
/**
* 對給定的明文進行 AES 加密,并返回 Base64 編碼后的密文字符串。
*
* @param plainText 明文字符串
* @return Base64 編碼后的密文字符串,如果加密過程中發(fā)生異常則返回 null
*/
public static String encrypt(String plainText) {
try {
// 獲取 Cipher 實例,指定使用 AES/CBC/PKCS5Padding 模式
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 構造密鑰規(guī)范
SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes("UTF-8"), "AES");
// 構造初始向量規(guī)范
IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes("UTF-8"));
// 初始化 Cipher 為加密模式
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
// 對明文進行加密
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
// 使用 Base64 對密文字節(jié)數(shù)組進行編碼,返回字符串
return Base64.getEncoder().encodeToString(encryptedBytes);
} catch (Exception e) {
// 捕獲異常并打印錯誤信息
e.printStackTrace();
return null;
}
}
/**
* 對給定的 Base64 編碼密文進行 AES 解密,還原出原始明文字符串。
*
* @param cipherText Base64 編碼后的密文字符串
* @return 解密后的明文字符串,如果解密過程中發(fā)生異常則返回 null
*/
public static String decrypt(String cipherText) {
try {
// 獲取 Cipher 實例,指定使用 AES/CBC/PKCS5Padding 模式
Cipher cipher = Cipher.getInstance(ALGORITHM);
// 構造密鑰規(guī)范
SecretKeySpec keySpec = new SecretKeySpec(KEY.getBytes("UTF-8"), "AES");
// 構造初始向量規(guī)范
IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes("UTF-8"));
// 初始化 Cipher 為解密模式
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
// 將 Base64 編碼的密文轉(zhuǎn)換為字節(jié)數(shù)組
byte[] decodedBytes = Base64.getDecoder().decode(cipherText);
// 對密文進行解密
byte[] decryptedBytes = cipher.doFinal(decodedBytes);
// 將解密后的字節(jié)數(shù)組轉(zhuǎn)換為字符串
return new String(decryptedBytes, "UTF-8");
} catch (Exception e) {
// 捕獲異常并打印錯誤信息
e.printStackTrace();
return null;
}
}
/**
* 主函數(shù),演示 AES 加密和解密的完整流程。
*
* @param args 命令行參數(shù)(未使用)
*/
public static void main(String[] args) {
// 定義待加密的明文
String plainText = "Hello, AES Encryption!";
System.out.println("原始明文: " + plainText);
// 對明文進行加密
String encryptedText = encrypt(plainText);
System.out.println("加密后的密文 (Base64 編碼): " + encryptedText);
// 對密文進行解密
String decryptedText = decrypt(encryptedText);
System.out.println("解密后的明文: " + decryptedText);
}
}
5. 代碼解讀
5.1 密鑰和初始向量設置
- KEY 和 IV
- 本示例中密鑰和初始向量均為固定字符串,長度均為 16 字節(jié),適用于 AES-128。
- 實際應用中,應使用安全隨機數(shù)生成密鑰和 IV,并對 IV 進行傳輸或存儲(例如,將 IV 附加在密文前)。
5.2 加密過程
- Cipher 獲取與初始化使用
Cipher.getInstance("AES/CBC/PKCS5Padding")獲取 Cipher 對象,并利用SecretKeySpec和IvParameterSpec初始化 Cipher 為加密模式。 - 數(shù)據(jù)加密將明文轉(zhuǎn)換為字節(jié)數(shù)組后調(diào)用
doFinal()方法進行加密,生成密文字節(jié)數(shù)組;之后使用 Base64 編碼便于輸出和存儲。
5.3 解密過程
- Cipher 初始化為解密模式同樣使用
SecretKeySpec和IvParameterSpec初始化 Cipher 為解密模式。 - 數(shù)據(jù)解密將 Base64 解碼后的密文字節(jié)數(shù)組傳入
doFinal()方法進行解密,還原出原始明文字節(jié)數(shù)組,再轉(zhuǎn)換為字符串。
5.4 異常處理
- 在加密和解密過程中均使用 try-catch 捕獲可能出現(xiàn)的異常,并輸出堆棧信息,確保程序調(diào)試和排查問題時能獲得足夠的信息。
6. 項目總結(jié)與展望
本項目通過 Java 實現(xiàn)了 AES 加密和解密的基本流程,主要收獲和體會包括:
掌握對稱加密基本原理學習了如何使用同一密鑰對數(shù)據(jù)進行加密和解密,并理解了 AES 加密中密鑰與初始向量的重要性。
熟悉 Java 加密 API通過 Cipher、SecretKeySpec、IvParameterSpec 等類的使用,掌握了 Java 內(nèi)置加密工具的基本操作。
安全性與實際應用雖然本示例使用固定的 IV 僅供學習,但在實際應用中應采用隨機 IV 并妥善管理密鑰,確保數(shù)據(jù)加密安全性。
擴展與優(yōu)化方向
- 可改進為生成隨機 IV,并將 IV 與密文組合(例如將 IV 前置于密文中一起傳輸)。
- 可以使用更高位數(shù)的 AES 加密(如 AES-256),前提是環(huán)境支持。
- 將加密/解密過程封裝為工具類,便于在實際項目中復用和集成。
總之,本項目為開發(fā)者提供了一個簡單、直觀的 AES 加密/解密示例,既有助于理解對稱加密的基本流程,也為構建實際安全通信系統(tǒng)提供了實踐基礎。希望這篇博客文章能為你在 Java 安全編程領域提供有價值的參考和啟發(fā)。
總結(jié)
到此這篇關于java AES加密/解密實現(xiàn)的文章就介紹到這了,更多相關java AES加密解密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
IDEA中使用Docker Compose容器編排的實現(xiàn)
這篇文章主要介紹了IDEA中使用Docker Compose容器編排的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-07-07
基于java servlet過濾器和監(jiān)聽器(詳解)
下面小編就為大家?guī)硪黄趈ava servlet過濾器和監(jiān)聽器(詳解)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10
Spring Cloud Alibaba 之 Nacos教程詳解
Nacos是阿里的一個開源產(chǎn)品,它是針對微服務架構中的服務發(fā)現(xiàn)、配置管理、服務治理的綜合性解決方案。這篇文章主要介紹了Spring Cloud Alibaba 之 Nacos的相關知識,需要的朋友可以參考下2020-11-11
spring boot使用自定義的線程池執(zhí)行Async任務
這篇文章主要介紹了spring boot使用自定義的線程池執(zhí)行Async任務的相關資料,需要的朋友可以參考下2018-02-02
spring boot自定義配置時在yml文件輸入有提示問題及解決方案
自定義一個配置類,然后在yml文件具體配置值時,一般不會有提示,今天小編給大家分享spring boot自定義配置時在yml文件輸入有提示問題,感興趣的朋友一起看看吧2023-10-10
SpringBoot?實現(xiàn)自定義的?@ConditionalOnXXX?注解示例詳解
這篇文章主要介紹了SpringBoot?實現(xiàn)自定義的?@ConditionalOnXXX?注解,通過示例代碼介紹了實現(xiàn)一個自定義的?@Conditional?派生注解,Conditional?派生注解的類如何注入到?spring?容器,需要的朋友可以參考下2022-08-08

