SpringBoot實現(xiàn)接口加密的五大技巧分享
5大神器,讓接口“秒變”加密大師
神器1:RSA+AES混合加密——加密界的“黃金CP”
目標:用RSA加密AES密鑰,用AES加密數(shù)據(jù),實現(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ù)端生成密鑰對)
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工具類(對稱加密)
public class AESUtil {
private static final String AES_ALGORITHM = "AES/CBC/PKCS7Padding";
// ?? 生成AES密鑰和偏移量(客戶端隨機生成)
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é)固定長度
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)鍵點:
- 對比純RSA:
// 純RSA:加密慢,且無法加密超過密鑰長度的數(shù)據(jù) // 混合加密:RSA加密小數(shù)據(jù)(AES密鑰),AES加密大數(shù)據(jù)(請求參數(shù))
神器2:自定義注解——給接口裝個“加密開關(guān)”
目標:用注解標記需要加密的接口,實現(xiàn)“按需加密”。
代碼示例(自定義注解):
import java.lang.annotation.*;
// ?? 自定義@RequestRSA注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestRSA {
// 可擴展字段(如加密版本號)
}
神器3:AOP自動解密——讓解密“隱形”
目標:通過AOP攔截請求,自動解密參數(shù),無需手動處理。
代碼示例(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?? 獲取原始請求參數(shù)(JSON格式)
Object[] args = joinPoint.getArgs();
String rawBody = args[0].toString(); // 假設(shè)第一個參數(shù)是請求體
// 2?? 解析sym和asy參數(shù)
JSONObject bodyJson = JSONObject.parseObject(rawBody);
String sym = bodyJson.getString("sym"); // RSA加密的AES密鑰
String asy = bodyJson.getString("asy"); // AES加密的請求參數(shù)
// 3?? 解密AES密鑰(使用RSA私鑰)
byte[] encryptedAESKey = Base64.getDecoder().decode(sym);
byte[] decryptedAESKey = RSAUtil.decryptRSA(encryptedAESKey, getPrivateKey()); // 需實現(xiàn)私鑰獲取邏輯
// 4?? 解密請求參數(shù)(使用AES密鑰)
byte[] aesKey = new SecretKeySpec(decryptedAESKey, "AES"); // 轉(zhuǎn)換為SecretKey
byte[] decryptedData = AESUtil.decryptAES(
Base64.getDecoder().decode(asy),
aesKey,
generateIV() // 需從參數(shù)中提取IV(此處簡化)
);
// 5?? 將解密后的參數(shù)綁定到接口入?yún)ο?
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);
}
// ?? 私鑰獲取(需替換為實際私鑰)
private PrivateKey getPrivateKey() {
// 從文件或內(nèi)存中加載私鑰(此處簡化)
return null;
}
}
關(guān)鍵點:
- 自動解密流程:
// 前端 → 發(fā)送 {sym: "RSA加密的AES密鑰", asy: "AES加密的參數(shù)"}
// 后端 → 自動解密 → 參數(shù)自動綁定到接口入?yún)ο?
神器4:異常處理——讓系統(tǒng)“防崩防炸”
目標:優(yōu)雅處理解密失敗場景,避免接口崩潰。
代碼示例(全局異常處理):
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("? 密鑰錯誤或請求過期!");
}
return ResponseEntity.status(500).body("內(nèi)部錯誤!");
}
}
神器5:全流程演示——從生成密鑰到調(diào)用接口
目標:實戰(zhàn)演示如何生成密鑰、加密請求、解密響應(yīng)。
代碼示例(全流程):
// ?? 服務(wù)端:生成RSA密鑰對
KeyPair rsaKeyPair = RSAUtil.generateRSAKeyPair();
PublicKey publicKey = rsaKeyPair.getPublic(); // 分發(fā)給客戶端
PrivateKey privateKey = rsaKeyPair.getPrivate(); // 服務(wù)端保存
// ?? 客戶端:加密請求
// 1?? 生成AES密鑰和偏移量
SecretKey aesKey = AESUtil.generateAESKey();
IvParameterSpec iv = AESUtil.generateIV();
// 2?? 加密真實參數(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ā)送請求
RequestBody requestBody = new RequestBody() {
"sym": Base64.getEncoder().encodeToString(encryptedMeta),
"asy": Base64.getEncoder().encodeToString(encryptedParams)
};
// → 后端自動解密并返回結(jié)果
你的接口,現(xiàn)在是“防破解超接口”了嗎?
通過這5大神器,我們實現(xiàn)了:
- RSA+AES混合加密:速度與安全兼得,破解者“一臉懵”。
- 自定義@RequestRSA注解:按需加密,代碼更優(yōu)雅。
- AOP自動解密:參數(shù)自動綁定,開發(fā)者“零感知”。
- 全局異常處理:解密失敗也能優(yōu)雅報錯。
- 全流程演示:從密鑰生成到接口調(diào)用,手把手教你落地。
到此這篇關(guān)于SpringBoot實現(xiàn)接口加密的五大技巧分享的文章就介紹到這了,更多相關(guān)SpringBoot接口加密技巧內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實現(xiàn)十六進制字符unicode與中英文轉(zhuǎn)換示例
當需要對一個unicode十六進制字符串進行編碼時,首先做的應(yīng)該是確認字符集編碼格式,在無法快速獲知的情況下,通過一下的str4all方法可以達到這一目的2014-02-02

