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é)固定長度 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:加密慢,且無法加密超過密鑰長度的數(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(此處簡化) ); // 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)存中加載私鑰(此處簡化) 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-06MyBatis-Plus通用CRUD操作的實(shí)現(xiàn)
MyBatis-Plus是基于MyBatis的增強(qiáng)工具,主要目的是簡化MyBatis的使用并提升開發(fā)效率,它提供了通可以用CRUD操作、分頁插件、多種插件支持、自動(dòng)代碼生成器等功能,感興趣的可以了解一下2024-10-10Springboot上傳文件時(shí)提示405問題及排坑過程
這篇文章主要介紹了Springboot上傳文件時(shí)提示405問題及排坑過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07