Java常用加密算法詳解與示例代碼
1. 前言
在信息安全領(lǐng)域,加密算法是保護(hù)數(shù)據(jù)機(jī)密性、完整性和身份認(rèn)證的核心手段。Java 標(biāo)準(zhǔn)庫(kù)及第三方框架(如 BouncyCastle)提供了豐富的加解密實(shí)現(xiàn),這里小編將結(jié)合 Java 代碼,詳細(xì)介紹常用的幾類加密算法,并給出可直接運(yùn)行的測(cè)試示例,幫助小伙伴們快速上手。
2. 加密算法基礎(chǔ)分類
2.1 哈希算法
- 特點(diǎn):?jiǎn)蜗虿豢赡?,固定長(zhǎng)度輸出
- 用途:數(shù)據(jù)完整性驗(yàn)證、密碼存儲(chǔ)
- 代表算法:
MD5、SHA-1、SHA-256、SHA-512
2.2 對(duì)稱加密算法
- 特點(diǎn):加密解密使用相同密鑰
- 優(yōu)勢(shì):速度快,適合大數(shù)據(jù)量加密
- 代表算法:
AES、DES、3DES、RC4
2.3 非對(duì)稱加密算法
- 特點(diǎn):公鑰加密,私鑰解密
- 優(yōu)勢(shì):安全性高,解決密鑰分發(fā)問(wèn)題
- 代表算法:
RSA、ECC、DSA
2.4 消息認(rèn)證碼(MAC)
- 特點(diǎn):帶密鑰的哈希函數(shù)
- 用途:驗(yàn)證消息完整性和來(lái)源
- 代表算法:
HMAC
3. 哈希算法
3.1 原理與特點(diǎn)
Hash(摘要):將任意長(zhǎng)度的數(shù)據(jù)“壓縮”成定長(zhǎng)的輸出,常用于數(shù)據(jù)完整性校驗(yàn)。
不可逆:無(wú)法從摘要反向推算原文;對(duì)抗碰撞攻擊(不同輸入產(chǎn)生相同輸出)是設(shè)計(jì)目標(biāo)之一。

3.2 Java 示例
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class HashUtils {
public static String hash(String input, String algorithm) {
try {
MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] digest = md.digest(input.getBytes());
// 轉(zhuǎn)為十六進(jìn)制
StringBuilder sb = new StringBuilder();
for (byte b : digest) {
sb.append(String.format("%02x", b & 0xff));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Unknown algorithm: " + algorithm, e);
}
}
// 測(cè)試主函數(shù)
public static void main(String[] args) {
String text = "HelloWorld";
System.out.println("MD5: " + hash(text, "MD5"));
System.out.println("SHA-1: " + hash(text, "SHA-1"));
System.out.println("SHA-256:" + hash(text, "SHA-256"));
}
}
運(yùn)行后,你將看到三種摘要值,驗(yàn)證不同算法的輸出長(zhǎng)度和差異。
4. 對(duì)稱加密算法
對(duì)稱加密使用同一個(gè)密鑰進(jìn)行加解密,速度快,適合大數(shù)據(jù)量場(chǎng)景。
由于 DES 已較為過(guò)時(shí),不推薦在新項(xiàng)目中使用,這里就不做DES介紹了,下面主要講解一下AES

2.1 AES(Advanced Encryption Standard)
密鑰長(zhǎng)度:128/192/256 位
模式:ECB(電子密碼本)、CBC(密碼分組鏈接)等;CBC 更安全但需 IV
2.2 AES 示例
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.util.Base64;
public class AESUtils {
// 生成 AES 密鑰
public static SecretKey genKey(int keySize) throws Exception {
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(keySize);
return kg.generateKey();
}
// 加密
public static String encrypt(String plaintext, SecretKey key, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] encrypted = cipher.doFinal(plaintext.getBytes());
return Base64.getEncoder().encodeToString(encrypted);
}
// 解密
public static String decrypt(String ciphertext, SecretKey key, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decoded = Base64.getDecoder().decode(ciphertext);
byte[] decrypted = cipher.doFinal(decoded);
return new String(decrypted);
}
public static void main(String[] args) throws Exception {
String text = "SecretMessage";
SecretKey key = genKey(128);
// 隨機(jī) IV,也可使用固定 IV(不推薦)
byte[] ivBytes = new byte[16];
System.arraycopy("RandomInitVector".getBytes(), 0, ivBytes, 0, 16);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
String cipherText = encrypt(text, key, iv);
String plainText = decrypt(cipherText, key, iv);
System.out.println("原文: " + text);
System.out.println("加密: " + cipherText);
System.out.println("解密: " + plainText);
}
}
5. 非對(duì)稱加密算法
5.1 RSA算法

算法特點(diǎn):
基于大數(shù)分解難題
密鑰長(zhǎng)度:1024-4096位
用途:數(shù)字簽名、密鑰交換
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class RSAExample {
public static void main(String[] args) throws Exception {
String plainText = "Java非對(duì)稱加密算法";
// 生成密鑰對(duì)
KeyPair keyPair = generateRSAKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 公鑰加密
byte[] cipherText = encryptRSA(plainText, publicKey);
System.out.println("RSA加密結(jié)果: " + Base64.getEncoder().encodeToString(cipherText));
// 私鑰解密
String decryptedText = decryptRSA(cipherText, privateKey);
System.out.println("RSA解密結(jié)果: " + decryptedText);
// 數(shù)字簽名示例
byte[] signature = signData(plainText, privateKey);
boolean isValid = verifySignature(plainText, signature, publicKey);
System.out.println("簽名驗(yàn)證結(jié)果: " + isValid);
}
public static KeyPair generateRSAKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048); // 密鑰長(zhǎng)度
return keyPairGenerator.generateKeyPair();
}
public static byte[] encryptRSA(String plainText, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
}
public static String decryptRSA(byte[] cipherText, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(cipherText);
return new String(decryptedBytes, StandardCharsets.UTF_8);
}
public static byte[] signData(String data, PrivateKey privateKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
return signature.sign();
}
public static boolean verifySignature(String data, byte[] signatureBytes, PublicKey publicKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initVerify(publicKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
return signature.verify(signatureBytes);
}
}
5.2 ECC(橢圓曲線加密)

算法特點(diǎn):
同等安全強(qiáng)度下密鑰更短
計(jì)算效率高
適合移動(dòng)設(shè)備
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class ECCExample {
public static void main(String[] args) throws Exception {
String plainText = "Java橢圓曲線加密";
// 生成密鑰對(duì)
KeyPair keyPair = generateECCKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 密鑰序列化/反序列化演示
String pubKeyStr = Base64.getEncoder().encodeToString(publicKey.getEncoded());
String priKeyStr = Base64.getEncoder().encodeToString(privateKey.getEncoded());
// 從字符串恢復(fù)密鑰
PublicKey restoredPubKey = restoreECCPublicKey(pubKeyStr);
PrivateKey restoredPriKey = restoreECCPrivateKey(priKeyStr);
// 數(shù)字簽名
byte[] signature = signDataECC(plainText, restoredPriKey);
boolean isValid = verifySignatureECC(plainText, signature, restoredPubKey);
System.out.println("ECC簽名驗(yàn)證結(jié)果: " + isValid);
}
public static KeyPair generateECCKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");
keyPairGenerator.initialize(256); // 密鑰長(zhǎng)度
return keyPairGenerator.generateKeyPair();
}
public static PublicKey restoreECCPublicKey(String keyStr) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(keyStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
return keyFactory.generatePublic(keySpec);
}
public static PrivateKey restoreECCPrivateKey(String keyStr) throws Exception {
byte[] keyBytes = Base64.getDecoder().decode(keyStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("EC");
return keyFactory.generatePrivate(keySpec);
}
public static byte[] signDataECC(String data, PrivateKey privateKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initSign(privateKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
return signature.sign();
}
public static boolean verifySignatureECC(String data, byte[] signatureBytes, PublicKey publicKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withECDSA");
signature.initVerify(publicKey);
signature.update(data.getBytes(StandardCharsets.UTF_8));
return signature.verify(signatureBytes);
}
}
6. 消息認(rèn)證碼(HMAC)
HMAC 用于驗(yàn)證數(shù)據(jù)完整性及認(rèn)證,結(jié)合了 Hash 與密鑰。
算法特點(diǎn):
輸入:密鑰 + 消息 → 通過(guò) Hash 計(jì)算,輸出固定長(zhǎng)度摘要。
常見(jiàn)算法:HmacMD5、HmacSHA1、HmacSHA256
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
public class HMACExample {
public static void main(String[] args) throws Exception {
String message = "重要業(yè)務(wù)數(shù)據(jù)";
String secretKey = "MySecretKey123";
// 計(jì)算HMAC
String hmac = calculateHMAC(message, secretKey);
System.out.println("HMAC-SHA256: " + hmac);
// 驗(yàn)證消息完整性
String receivedMessage = "重要業(yè)務(wù)數(shù)據(jù)";
String receivedHmac = calculateHMAC(receivedMessage, secretKey);
System.out.println("HMAC驗(yàn)證結(jié)果: " + hmac.equals(receivedHmac));
}
public static String calculateHMAC(String data, String key)
throws NoSuchAlgorithmException, InvalidKeyException {
Mac sha256Hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(
key.getBytes(StandardCharsets.UTF_8),
"HmacSHA256"
);
sha256Hmac.init(secretKey);
byte[] hmacBytes = sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hmacBytes);
}
}
7. 總結(jié)
本文博主介紹了四大類經(jīng)典加密算法在 Java 中的實(shí)現(xiàn)方式:
- 哈希算法:MD5、SHA-1、SHA-256,用于數(shù)據(jù)完整性校驗(yàn);
- 對(duì)稱加密:AES、DES,適合大數(shù)據(jù)量加密;
- 非對(duì)稱加密:RSA,實(shí)現(xiàn)密鑰交換和數(shù)字簽名;
- 消息認(rèn)證碼:HMAC,用于完整性與認(rèn)證。
在生產(chǎn)環(huán)境中,建議優(yōu)先選用 AES(至少 128 位)、SHA-256、RSA 2048 位以上,并嚴(yán)格管理密鑰和 IV,以確保安全性。希望本文能幫助小伙伴快速掌握 Java 加密實(shí)戰(zhàn)!
以上就是Java常用加密算法詳解與示例代碼的詳細(xì)內(nèi)容,更多關(guān)于Java常用加密算法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
IntelliJ?IDEA2022.3?springboot?熱部署含靜態(tài)文件(最新推薦)
這篇文章主要介紹了IntelliJ?IDEA2022.3?springboot?熱部署含靜態(tài)文件,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-01-01
Spring MVC 處理一個(gè)請(qǐng)求的流程
Spring MVC是Spring系列框架中使用頻率最高的部分。不管是Spring Boot還是傳統(tǒng)的Spring項(xiàng)目,只要是Web項(xiàng)目都會(huì)使用到Spring MVC部分。因此程序員一定要熟練掌握MVC部分。本篇博客簡(jiǎn)要分析Spring MVC處理一個(gè)請(qǐng)求的流程。2021-02-02
java使用正則表達(dá)校驗(yàn)手機(jī)號(hào)碼示例(手機(jī)號(hào)碼正則)
這篇文章主要介紹了java使用正則表達(dá)校驗(yàn)手機(jī)號(hào)碼示例,可校驗(yàn)三個(gè)號(hào)碼段:13*、15*、18*,大家根據(jù)自己的需要增加自己的號(hào)碼段就可以了2014-03-03
tio-boot整合hotswap-classloader實(shí)現(xiàn)熱加載方法實(shí)例
這篇文章主要為大家介紹了tio-boot整合hotswap-classloader實(shí)現(xiàn)熱加載方法實(shí)例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
java Swing實(shí)現(xiàn)選項(xiàng)卡功能(JTabbedPane)實(shí)例代碼
這篇文章主要介紹了java Swing實(shí)現(xiàn)選項(xiàng)卡功能(JTabbedPane)實(shí)例代碼的相關(guān)資料,學(xué)習(xí)java 基礎(chǔ)的朋友可以參考下這個(gè)簡(jiǎn)單示例,需要的朋友可以參考下2016-11-11
java并發(fā)等待條件的實(shí)現(xiàn)原理詳解
這篇文章主要介紹了java并發(fā)等待條件的實(shí)現(xiàn)原理詳解,還是比較不錯(cuò)的,這里分享給大家,供需要的朋友參考。2017-11-11
IntelliJ?IDEA?代碼運(yùn)行時(shí)中文出現(xiàn)亂碼問(wèn)題及解決方法
在我們剛接觸到IDEA時(shí),想美滋滋的敲一個(gè)“hello?world”來(lái)問(wèn)候這個(gè)世界,但難免會(huì)遇到這種問(wèn)題亂碼,這篇文章主要介紹了解決IntelliJ?IDEA?代碼運(yùn)行時(shí)中文出現(xiàn)亂碼問(wèn)題,需要的朋友可以參考下2023-09-09

