SpringBoot實(shí)現(xiàn)接口加密的五大技巧分享
5大神器,讓接口“秒變”加密大師
神器1:RSA+AES混合加密——加密界的“黃金CP”
目標(biāo):用RSA加密AES密鑰,用AES加密數(shù)據(jù),實(shí)現(xiàn)“速度與安全兼得”。
代碼示例(加密工具類):
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.KeyFactory;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
// ?? RSA工具類(服務(wù)端生成密鑰對(duì))
public class RSAUtil {
private static final String RSA_ALGORITHM = "RSA/ECB/PKCS1Padding";
// ?? 生成RSA公鑰和私鑰(服務(wù)端執(zhí)行一次)
public static KeyPair generateRSAKeyPair() throws Exception {
KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
generator.initialize(2048); // 推薦2048位以上
return generator.generateKeyPair();
}
// ?? 用RSA公鑰加密AES密鑰
public static byte[] encryptRSA(byte[] data, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
// ?? 用RSA私鑰解密AES密鑰
public static byte[] decryptRSA(byte[] encryptedData, PrivateKey privateKey) throws Exception {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(encryptedData);
}
}
// ?? AES工具類(對(duì)稱加密)
public class AESUtil {
private static final String AES_ALGORITHM = "AES/CBC/PKCS7Padding";
// ?? 生成AES密鑰和偏移量(客戶端隨機(jī)生成)
public static SecretKey generateAESKey() {
return new SecretKeySpec(KeyGenerator.getInstance("AES").generateKey().getEncoded(), "AES");
}
// ?? 生成AES偏移量(IV)
public static IvParameterSpec generateIV() {
byte[] iv = new byte[16]; // 16字節(jié)固定長(zhǎng)度
new SecureRandom().nextBytes(iv);
return new IvParameterSpec(iv);
}
// ?? AES加密數(shù)據(jù)
public static byte[] encryptAES(byte[] data, SecretKey key, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal(data);
}
// ?? AES解密數(shù)據(jù)
public static byte[] decryptAES(byte[] encryptedData, SecretKey key, IvParameterSpec iv) throws Exception {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(encryptedData);
}
}
關(guān)鍵點(diǎn):
- 對(duì)比純RSA:
// 純RSA:加密慢,且無法加密超過密鑰長(zhǎng)度的數(shù)據(jù) // 混合加密:RSA加密小數(shù)據(jù)(AES密鑰),AES加密大數(shù)據(jù)(請(qǐng)求參數(shù))
神器2:自定義注解——給接口裝個(gè)“加密開關(guān)”
目標(biāo):用注解標(biāo)記需要加密的接口,實(shí)現(xiàn)“按需加密”。
代碼示例(自定義注解):
import java.lang.annotation.*;
// ?? 自定義@RequestRSA注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestRSA {
// 可擴(kuò)展字段(如加密版本號(hào))
}
神器3:AOP自動(dòng)解密——讓解密“隱形”
目標(biāo):通過AOP攔截請(qǐng)求,自動(dòng)解密參數(shù),無需手動(dòng)處理。
代碼示例(AOP切面):
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import com.alibaba.fastjson.JSONObject;
@Aspect
@Component
public class RSAAspect {
@Around("@annotation(RequestRSA)")
public Object decryptRequest(ProceedingJoinPoint joinPoint) throws Throwable {
// 1?? 獲取原始請(qǐng)求參數(shù)(JSON格式)
Object[] args = joinPoint.getArgs();
String rawBody = args[0].toString(); // 假設(shè)第一個(gè)參數(shù)是請(qǐng)求體
// 2?? 解析sym和asy參數(shù)
JSONObject bodyJson = JSONObject.parseObject(rawBody);
String sym = bodyJson.getString("sym"); // RSA加密的AES密鑰
String asy = bodyJson.getString("asy"); // AES加密的請(qǐng)求參數(shù)
// 3?? 解密AES密鑰(使用RSA私鑰)
byte[] encryptedAESKey = Base64.getDecoder().decode(sym);
byte[] decryptedAESKey = RSAUtil.decryptRSA(encryptedAESKey, getPrivateKey()); // 需實(shí)現(xiàn)私鑰獲取邏輯
// 4?? 解密請(qǐng)求參數(shù)(使用AES密鑰)
byte[] aesKey = new SecretKeySpec(decryptedAESKey, "AES"); // 轉(zhuǎn)換為SecretKey
byte[] decryptedData = AESUtil.decryptAES(
Base64.getDecoder().decode(asy),
aesKey,
generateIV() // 需從參數(shù)中提取IV(此處簡(jiǎn)化)
);
// 5?? 將解密后的參數(shù)綁定到接口入?yún)?duì)象
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Object target = joinPoint.getTarget();
Method method = signature.getMethod();
Object[] newArgs = new Object[]{JSONObject.parseObject(new String(decryptedData), method.getParameterTypes()[0])};
// 6?? 繼續(xù)執(zhí)行原方法
return joinPoint.proceed(newArgs);
}
// ?? 私鑰獲?。ㄐ杼鎿Q為實(shí)際私鑰)
private PrivateKey getPrivateKey() {
// 從文件或內(nèi)存中加載私鑰(此處簡(jiǎn)化)
return null;
}
}
關(guān)鍵點(diǎn):
- 自動(dòng)解密流程:
// 前端 → 發(fā)送 {sym: "RSA加密的AES密鑰", asy: "AES加密的參數(shù)"}
// 后端 → 自動(dòng)解密 → 參數(shù)自動(dòng)綁定到接口入?yún)?duì)象
神器4:異常處理——讓系統(tǒng)“防崩防炸”
目標(biāo):優(yōu)雅處理解密失敗場(chǎng)景,避免接口崩潰。
代碼示例(全局異常處理):
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handleException(Exception e) {
if (e.getMessage().contains("解密失敗")) {
return ResponseEntity.status(400).body("? 密鑰錯(cuò)誤或請(qǐng)求過期!");
}
return ResponseEntity.status(500).body("內(nèi)部錯(cuò)誤!");
}
}
神器5:全流程演示——從生成密鑰到調(diào)用接口
目標(biāo):實(shí)戰(zhàn)演示如何生成密鑰、加密請(qǐng)求、解密響應(yīng)。
代碼示例(全流程):
// ?? 服務(wù)端:生成RSA密鑰對(duì)
KeyPair rsaKeyPair = RSAUtil.generateRSAKeyPair();
PublicKey publicKey = rsaKeyPair.getPublic(); // 分發(fā)給客戶端
PrivateKey privateKey = rsaKeyPair.getPrivate(); // 服務(wù)端保存
// ?? 客戶端:加密請(qǐng)求
// 1?? 生成AES密鑰和偏移量
SecretKey aesKey = AESUtil.generateAESKey();
IvParameterSpec iv = AESUtil.generateIV();
// 2?? 加密真實(shí)參數(shù)(如JSON字符串)
String originalParams = "{\"username\":\"張三\", \"age\":18}";
byte[] encryptedParams = AESUtil.encryptAES(
originalParams.getBytes(),
aesKey,
iv
);
// 3?? 將AES密鑰和元數(shù)據(jù)用RSA加密
JSONObject meta = new JSONObject();
meta.put("key", Base64.getEncoder().encodeToString(aesKey.getEncoded()));
meta.put("keyVI", Base64.getEncoder().encodeToString(iv.getIV()));
meta.put("time", System.currentTimeMillis());
byte[] encryptedMeta = RSAUtil.encryptRSA(
meta.toJSONString().getBytes(),
publicKey // 客戶端需提前獲取公鑰
);
// 4?? 發(fā)送請(qǐng)求
RequestBody requestBody = new RequestBody() {
"sym": Base64.getEncoder().encodeToString(encryptedMeta),
"asy": Base64.getEncoder().encodeToString(encryptedParams)
};
// → 后端自動(dòng)解密并返回結(jié)果
你的接口,現(xiàn)在是“防破解超接口”了嗎?
通過這5大神器,我們實(shí)現(xiàn)了:
- RSA+AES混合加密:速度與安全兼得,破解者“一臉懵”。
- 自定義@RequestRSA注解:按需加密,代碼更優(yōu)雅。
- AOP自動(dòng)解密:參數(shù)自動(dòng)綁定,開發(fā)者“零感知”。
- 全局異常處理:解密失敗也能優(yōu)雅報(bào)錯(cuò)。
- 全流程演示:從密鑰生成到接口調(diào)用,手把手教你落地。
到此這篇關(guān)于SpringBoot實(shí)現(xiàn)接口加密的五大技巧分享的文章就介紹到這了,更多相關(guān)SpringBoot接口加密技巧內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實(shí)現(xiàn)十六進(jìn)制字符unicode與中英文轉(zhuǎn)換示例
當(dāng)需要對(duì)一個(gè)unicode十六進(jìn)制字符串進(jìn)行編碼時(shí),首先做的應(yīng)該是確認(rèn)字符集編碼格式,在無法快速獲知的情況下,通過一下的str4all方法可以達(dá)到這一目的2014-02-02
帶你一文深入認(rèn)識(shí)Java?String類
這篇文章主要介紹了帶你一文深入認(rèn)識(shí)Java?String類,String 類在Java中是很常用的類,很重要的類,在后續(xù)的學(xué)習(xí)中經(jīng)常會(huì)用到,是后續(xù)學(xué)習(xí)的基礎(chǔ), 文章圍繞主題展開更多詳細(xì)內(nèi)容,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助2022-06-06
MyBatis-Plus通用CRUD操作的實(shí)現(xiàn)
MyBatis-Plus是基于MyBatis的增強(qiáng)工具,主要目的是簡(jiǎn)化MyBatis的使用并提升開發(fā)效率,它提供了通可以用CRUD操作、分頁(yè)插件、多種插件支持、自動(dòng)代碼生成器等功能,感興趣的可以了解一下2024-10-10
Springboot上傳文件時(shí)提示405問題及排坑過程
這篇文章主要介紹了Springboot上傳文件時(shí)提示405問題及排坑過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07

