javascript
Spring Data JPA 数据加密存储
數(shù)據(jù)安全永遠(yuǎn)是個(gè)大問題。用戶數(shù)據(jù)存儲(chǔ)到數(shù)據(jù)庫(kù)中,如果不采取加密手段,那么只要有權(quán)限訪問數(shù)據(jù)庫(kù)的人,都能直接明了的看到用戶所有的隱私數(shù)據(jù),尤其在中小型公司中,對(duì)于數(shù)據(jù)庫(kù)權(quán)限的管理基本上都是由開發(fā)人員直接進(jìn)行維護(hù)管理,這樣對(duì)于數(shù)據(jù)安全并不是一個(gè)好事,因此如果能將用戶私密數(shù)據(jù)加密存儲(chǔ)到數(shù)據(jù)庫(kù)中,那么就能稍微提升一些數(shù)據(jù)安全性。本文討論的是在
Spring Data JPA 中使用 AES 加解密來(lái)存儲(chǔ)用戶隱私數(shù)據(jù),使用的數(shù)據(jù)庫(kù)是 mysql。
首先,mysql 提供直接的加解密函數(shù) aes_encrypt() 和 aes_decrypt() ,我們就是直接使用這兩個(gè)函數(shù)。方法比較簡(jiǎn)單,在需要加解密的字段上,使用 @ColumnTransformer 注解,來(lái)調(diào)用aes_encrypt() 和 aes_decrypt() 函數(shù)。但需要注意的是,aes_encrypt() 加密之后是二進(jìn)制數(shù)據(jù),因此數(shù)據(jù)庫(kù)字段類型需要使用 blob,如果你的應(yīng)用是全新開發(fā)的,那么問題不大,但是如果需要在已有的項(xiàng)目中加上數(shù)據(jù)加密特性,那么你需要修改現(xiàn)有數(shù)據(jù)庫(kù)的庫(kù)表結(jié)構(gòu),這樣代價(jià)就比較大了,因此我們可以使用 mysql 的 hex() 函數(shù),將這個(gè)二進(jìn)制的數(shù)據(jù),轉(zhuǎn)換為十六進(jìn)制字符串存儲(chǔ)入數(shù)據(jù)庫(kù)中。同理,讀取時(shí)先用 unhex() 函數(shù)將十六進(jìn)制字符串重新轉(zhuǎn)換為二進(jìn)制數(shù)據(jù),再進(jìn)行解密操作得到最終結(jié)果。
@Column(name = "user_name")@ColumnTransformer( read = "AES_DECRYPT(UNHEX(user_name), 'ankon')",write = "HEX(AES_ENCRYPT(?, 'ankon'))")private String userName;上述方式解決了我們的基本問題,那么,中文呢?經(jīng)測(cè)試,這種方式解析中文完全不OK,因此我們還需要加點(diǎn)料:
@Column(name = "user_name")@ColumnTransformer( read = "CAST(AES_DECRYPT(UNHEX(user_name), 'ankon') as char(128))",write = "HEX(AES_ENCRYPT(?, 'ankon'))")private String userName;使用 cast ,將解析結(jié)果強(qiáng)制轉(zhuǎn)換成字符格式。
愿意猜想:因?yàn)闆]有去查看源碼(找起來(lái)實(shí)在是太麻煩了),所以就猜測(cè)下:當(dāng)我們不使用 cast 時(shí),JPA 從 mysql 獲取到的 userName 是一個(gè)解密后的二進(jìn)制數(shù)據(jù),但是那個(gè)字段本身聲明為 String, 那么它應(yīng)該有默認(rèn)的轉(zhuǎn)換方法將 byte[] 轉(zhuǎn)換為 String,畢竟是老外寫的,那么應(yīng)該不會(huì)去考慮多種亂七八糟的字符編碼,畢竟他們用 ISO-8859-1 就夠了,所以你看到的結(jié)果就是中文亂碼,英文OK。加上 cast 之后,在 mysql 層面將結(jié)果處理為字符串格式,mysql 的字符編碼格式為 utf-8 的話,那么就跟代碼層面需要的字符編碼格式一致了,因此就正常解析出來(lái)了。
轉(zhuǎn)發(fā)來(lái)自https://blog.csdn.net/zxcvqwer19900720/article/details/87189593
總結(jié)
以上是生活随笔為你收集整理的Spring Data JPA 数据加密存储的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html进度条实现原理,js实现进度条
- 下一篇: SpringMVC 数据绑定全面示例(复