SpringBoot結(jié)合MyBatis實(shí)現(xiàn)數(shù)據(jù)庫(kù)字段加密
今天分享一篇基于SpringBoot+MyBatis來(lái)實(shí)現(xiàn)數(shù)據(jù)庫(kù)字段加密的操作,喜歡的朋友可以借鑒
大致的實(shí)現(xiàn)流程
業(yè)務(wù)層-->系統(tǒng)攔截器-->數(shù)據(jù)庫(kù)-->系統(tǒng)攔截器-->返回結(jié)果
加密注解設(shè)計(jì)
把需要加密的字段通過(guò)我們自定義的加密注解進(jìn)行標(biāo)識(shí),所以我們需要先自定義一段加密注解的代碼
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Encrypt {
}實(shí)體類(lèi)
在實(shí)體類(lèi)上使用注解標(biāo)記需要加密字段
@Data
public class User {
private Long id;
private String username;
@Encrypt
private String password;
@Encrypt
private String email;
@Encrypt
private String phone;
}加密工具類(lèi)
基于AES加密算法實(shí)現(xiàn)對(duì)字段名的加密,大家可以選擇其他的加密算法
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è)計(jì)
通過(guò)攔截實(shí)現(xiàn)自動(dòng)加密和自動(dòng)解密
// 加密攔截器
@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命令類(lèi)型
String sqlCommandType = mappedStatement.getSqlCommandType().toString();
// 對(duì)INSERT和UPDATE操作進(jìn)行加密處理
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();
// 對(duì)查詢(xún)結(jié)果進(jìn)行解密處理
if (result instanceof List) {
List<?> list = (List<?>) result;
for (Object item : list) {
decryptFields(item);
}
} else {
decryptFields(result);
}
return result;
}
}
}測(cè)試場(chǎng)景
- 用戶(hù)信息保護(hù):在用戶(hù)注冊(cè)時(shí),自動(dòng)加密用戶(hù)的密碼、郵箱、手機(jī)號(hào)等敏感信息,即使數(shù)據(jù)庫(kù)泄露也不會(huì)造成用戶(hù)隱私泄露
- 金融數(shù)據(jù)保護(hù):對(duì)用戶(hù)的銀行卡號(hào)、交易記錄等金融數(shù)據(jù)進(jìn)行加密存儲(chǔ),滿(mǎn)足金融行業(yè)的合規(guī)要求
- 醫(yī)療醫(yī)保數(shù)據(jù)保護(hù):對(duì)患者的病歷、診斷結(jié)果等醫(yī)療隱私數(shù)據(jù)進(jìn)行加密,保護(hù)患者隱私
- 企業(yè)數(shù)據(jù)保護(hù):對(duì)企業(yè)內(nèi)部的商業(yè)機(jī)密、客戶(hù)資料等重要數(shù)據(jù)進(jìn)行加密保護(hù)
注意事項(xiàng)
- 雖然字段級(jí)加密功能強(qiáng)大,但在生產(chǎn)環(huán)境中使用時(shí)必須注意安全性:
- 密鑰管理:不要在代碼中硬編碼密鑰,應(yīng)使用專(zhuān)業(yè)的密鑰管理系統(tǒng)
- 算法選擇:使用經(jīng)過(guò)驗(yàn)證的加密算法,如AES-256
- 性能優(yōu)化:合理選擇需要加密的字段,避免對(duì)所有字段都進(jìn)行加密
- 審計(jì)日志:記錄所有加密解密操作,便于安全審計(jì)
- 定期輪換:定期更換加密密鑰,降低密鑰泄露風(fēng)險(xiǎn)
到此這篇關(guān)于SpringBoot結(jié)合MyBatis實(shí)現(xiàn)數(shù)據(jù)庫(kù)字段加密的文章就介紹到這了,更多相關(guān)SpringBoot MyBatis數(shù)據(jù)庫(kù)字段加密內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot+MyBatis實(shí)現(xiàn)數(shù)據(jù)庫(kù)字段級(jí)加密
- SpringBoot+MyBatis實(shí)現(xiàn)MD5加密數(shù)據(jù)庫(kù)用戶(hù)密碼的方法
- SpringBoot項(xiàng)目配置數(shù)據(jù)庫(kù)密碼加密相關(guān)代碼
- SpringBoot3使用Jasypt加密數(shù)據(jù)庫(kù)用戶(hù)名、密碼等敏感信息
- IDEA中SpringBoot項(xiàng)目數(shù)據(jù)庫(kù)連接加密方法
- springboot項(xiàng)目數(shù)據(jù)庫(kù)密碼如何加密
相關(guān)文章
關(guān)于使用MyBatis簡(jiǎn)化JDBC開(kāi)發(fā)和解決SQL語(yǔ)句警告的問(wèn)題
這篇文章主要介紹了關(guān)于使用MyBatis簡(jiǎn)化JDBC開(kāi)發(fā)和解決SQL語(yǔ)句警告的問(wèn)題,如果idea和數(shù)據(jù)庫(kù)沒(méi)有建立鏈接,idea不識(shí)別表的信息,就會(huì)出現(xiàn)SQL語(yǔ)句的警告,需要的朋友可以參考下2023-05-05
解決mybatis plus報(bào)錯(cuò)Invalid bound statement
在使用MyBatis時(shí)遇到InvalidBoundStatement異常,常因多個(gè)MapperScan配置沖突或者包掃描路徑設(shè)置錯(cuò)誤,解決方法包括保留一個(gè)MapperScan聲明、檢查jar包沖突、確保命名空間和掃描路徑正確,使用@TableId注解指定主鍵2024-11-11
elasticsearch構(gòu)造Client實(shí)現(xiàn)java客戶(hù)端調(diào)用接口示例分析
這篇文章主要為大家介紹了elasticsearch構(gòu)造Client實(shí)現(xiàn)java客戶(hù)端調(diào)用接口示例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
SpringBoot自定義消息轉(zhuǎn)換器的實(shí)現(xiàn)與應(yīng)用
Spring Boot 默認(rèn)提供了多種消息轉(zhuǎn)換器,如 Jackson 用于 JSON 格式轉(zhuǎn)換、JAXB 用于 XML 格式轉(zhuǎn)換等,然而,實(shí)際開(kāi)發(fā)中往往需要根據(jù)業(yè)務(wù)需求進(jìn)行自定義的消息轉(zhuǎn)換器,文將詳細(xì)介紹如何在 Spring Boot 中實(shí)現(xiàn)自定義消息轉(zhuǎn)換器,探討其工作原理、配置方式以及實(shí)際應(yīng)用場(chǎng)景2025-01-01
java集合與數(shù)組的相同點(diǎn)和不同點(diǎn)
今天小編就為大家分享一篇關(guān)于java集合與數(shù)組的相同點(diǎn)和不同點(diǎn),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-04-04
idea mabatisX插件生成mapper.xml文件全過(guò)程
文章介紹了如何在IntelliJ IDEA中使用MybatisX插件自動(dòng)生成MyBatis的Mapper和XML文件,步驟包括安裝插件、選擇數(shù)據(jù)庫(kù)表并右鍵選擇MybatisX-Generator進(jìn)行配置和生成2026-03-03
SpringBoot中使用@scheduled定時(shí)執(zhí)行任務(wù)的坑
本文主要介紹了SpringBoot中使用@scheduled定時(shí)執(zhí)行任務(wù)的坑,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05

