SpringBoot+MyBatis實現(xiàn)數(shù)據(jù)庫字段加密全過程
分享一篇基于SpringBoot+MyBatis來實現(xiàn)數(shù)據(jù)庫字段加密的操作,喜歡的朋友可以借鑒
大致的實現(xiàn)流程
業(yè)務(wù)層-->系統(tǒng)攔截器-->數(shù)據(jù)庫-->系統(tǒng)攔截器-->返回結(jié)果
加密注解設(shè)計
把需要加密的字段通過我們自定義的加密注解進行標識,所以我們需要先自定義一段加密注解的代碼
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Encrypt {
}實體類
在實體類上使用注解標記需要加密字段
@Data
public class User {
private Long id;
private String username;
@Encrypt
private String password;
@Encrypt
private String email;
@Encrypt
private String phone;
}加密工具類
基于AES加密算法實現(xiàn)對字段名的加密,大家可以選擇其他的加密算法
public class EncryptionUtil {
privatestaticfinal String ALGORITHM = "AES";
privatestaticfinal String TRANSFORMATION = "AES/ECB/PKCS5Padding";
// AES加密
public static String encrypt(String plainText, String key) {
try {
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
} catch (Exception e) {
thrownew RuntimeException("加密失敗", e);
}
}
// AES解密
public static String decrypt(String cipherText, String key) {
try {
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(cipherText));
returnnew String(decryptedBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
thrownew RuntimeException("解密失敗", e);
}
}
}系統(tǒng)攔截器設(shè)計
通過攔截實現(xiàn)自動加密和自動解密
// 加密攔截器
@Intercepts({
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
@Component
public class FieldEncryptionInterceptor implements Interceptor {
@Value("${encryption.key:mySecretKey12345}")
private String encryptionKey;
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
MappedStatement mappedStatement = (MappedStatement) args[0];
Object parameter = args[1];
// 獲取SQL命令類型
String sqlCommandType = mappedStatement.getSqlCommandType().toString();
// 對INSERT和UPDATE操作進行加密處理
if ("INSERT".equals(sqlCommandType) || "UPDATE".equals(sqlCommandType)) {
encryptFields(parameter);
}
return invocation.proceed();
}
// 解密攔截器
@Intercepts({
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
@Component
public class FieldDecryptionInterceptor implements Interceptor {
@Value("${encryption.key:mySecretKey12345}")
private String encryptionKey;
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 執(zhí)行原始方法
Object result = invocation.proceed();
// 對查詢結(jié)果進行解密處理
if (result instanceof List) {
List<?> list = (List<?>) result;
for (Object item : list) {
decryptFields(item);
}
} else {
decryptFields(result);
}
return result;
}
}
}測試場景
- 用戶信息保護:在用戶注冊時,自動加密用戶的密碼、郵箱、手機號等敏感信息,即使數(shù)據(jù)庫泄露也不會造成用戶隱私泄露
- 金融數(shù)據(jù)保護:對用戶的銀行卡號、交易記錄等金融數(shù)據(jù)進行加密存儲,滿足金融行業(yè)的合規(guī)要求
- 醫(yī)療醫(yī)保數(shù)據(jù)保護:對患者的病歷、診斷結(jié)果等醫(yī)療隱私數(shù)據(jù)進行加密,保護患者隱私
- 企業(yè)數(shù)據(jù)保護:對企業(yè)內(nèi)部的商業(yè)機密、客戶資料等重要數(shù)據(jù)進行加密保護
注意事項
雖然字段級加密功能強大,但在生產(chǎn)環(huán)境中使用時必須注意安全性:
- 密鑰管理:不要在代碼中硬編碼密鑰,應(yīng)使用專業(yè)的密鑰管理系統(tǒng)
- 算法選擇:使用經(jīng)過驗證的加密算法,如AES-256
- 性能優(yōu)化:合理選擇需要加密的字段,避免對所有字段都進行加密
- 審計日志:記錄所有加密解密操作,便于安全審計
- 定期輪換:定期更換加密密鑰,降低密鑰泄露風(fēng)險
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- springboot、Mybatis-plus工程多數(shù)據(jù)源字段映射不生效問題及解決
- 使用SpringBoot+MyBatis實現(xiàn)數(shù)據(jù)庫字段級加密
- SpringBoot結(jié)合MyBatis實現(xiàn)數(shù)據(jù)庫字段加密
- SpringBoot+MyBatis實現(xiàn)數(shù)據(jù)庫字段級加密
- SpringBoot基于MyBatisPlus實現(xiàn)公共字段自動填充
- SpringBoot+MyBatis Plus實現(xiàn)update_time字段自動更新詳解
- SpringBoot+MyBatis實現(xiàn)動態(tài)字段更新的三種方法
- SpringBoot?mybatis-plus使用json字段實戰(zhàn)指南
相關(guān)文章
SpringMVC實現(xiàn)返回響應(yīng)的項目實踐
本文主要介紹了SpringMVC實現(xiàn)返回響應(yīng)的項目實踐,包含返回靜態(tài)頁面,返回數(shù)據(jù),返回html片段等實例,具有一定的參考價值,感興趣的可以了解一下2024-02-02
Java發(fā)送帶html標簽內(nèi)容的郵件實例代碼
下面小編就為大家?guī)硪黄狫ava發(fā)送帶html標簽內(nèi)容的郵件實例代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11
解決java -jar XXX.jar沒有主清單屬性以及找不到或無法加載主類的問題
在使用Idea打包SpringBoot項目時,可能會遇到“沒有主清單屬性”的錯誤,問題原因是pom文件中缺少配置,未能正確打包成可執(zhí)行的jar,解決方法包括:1. 修改項目結(jié)構(gòu)并重新生成jar;2. 使用Maven插件在pom文件中添加spring-boot-maven-plugin配置2024-09-09
Spring Boot兩種配置文件properties和yml區(qū)別
這篇文章主要為大家介紹了java面試中常見問到的Spring Boot兩種配置文件properties和yml區(qū)別解答,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07

