日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

技术分享 | 详解SQL加密函数:AES_ENCRYPT()

發布時間:2023/12/20 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 技术分享 | 详解SQL加密函数:AES_ENCRYPT() 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:岳明強

愛可生北京分公司 DBA 團隊成員,人稱強哥,負責數據庫管理平臺的運維和 MySQL 問題處理。擅長對 MySQL 的故障定位。

本文來源:原創投稿

*愛可生開源社區出品,原創內容未經授權不得隨意使用,轉載請聯系小編并注明來源。


最近由于客戶對于 MySQL 數據加密有一些要求,特地對于 MySQL 的數據加密研究了一下。當前 MySQL 原生的數據加密有靜態加密,即加密數據庫的物理文件,防止直接拖庫后讀取敏感數據,還有 SQL 級別的加密,只加密部分字段,即使獲取到數據,也無法進行解讀。下面主要是對于 SQL 加密函數 AES_ENCRYPT() 的一些說明

參數說明

解密:AES_DECRYPT():AES_DECRYPT(crypt_str,key_str[,init_vector][,kdf_name][,salt][,info | iterations])

加密:AES_ENCRYPT(str,key_str[,init_vector][,kdf_name][,salt][,info | iterations])

srt:加密之后的字符串

crypt_str:用來加密的字符串,加密后的字段長度可以用以下公式計算,其中 trunc() 表示小數部分舍棄,即如果輸入單個字符,那么存儲的字段長度即為最短長度16

16 * (trunc(string_length / 16) + 1)

key_str:加密密鑰,不建議使用明文密鑰,應該先用hash處理一下

init_vector 初始向量,用于塊加密的模式(block_encryption_mode),默認的加密模式為aes-128-ecb,不需要初始向量,其它的加密模式(CBC、CFB1、CFB8、CFB128 和 OFB)都需要初始向量,其中 ecb 的加密模式并不安全,建議使用其它的加密模式,使用 init_vector 加密后 也要使用相同的 init_vector 解密

kdf_name,salt,info,iterations:為 KDF 的相關參數,相對于更加安全,官方建議使用,但由于版本要求過高(5.7.40以及8.0.30之后),這里就先不考慮了

使用說明

使用官方 AES(高級加密標準)算法解密數據,默認使用128-bit也可以使用196或者256,密鑰的長度與性能和安全度有關,

使用 AES_ENCRYPT()對于基于 statement 的 binlog 類型是不安全的,建議使用 SSL 連接,防止將加密函數的密碼和其它敏感值作為明文發送到服務器。

簡單示例:

mysql [localhost:5734] {root} (test) > show create table test; +-------+-----------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +-------+-----------------------------------------------------------------------------------------------------------------------+ | test | CREATE TABLE `test` (`n` char(200) DEFAULT NULL,`t` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1 | +-------+-----------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)mysql [localhost:5734] {root} (test) > insert into test values(aes_encrypt('b','test'),1); Query OK, 1 row affected (0.00 sec)mysql [localhost:5734] {root} (test) > select * from test; +----------------------------+------+ | n | t | +----------------------------+------+ | x | 0 | | y | 0 | | ùp?U!??§ò?WH??ò | 1 | +----------------------------+------+ 3 rows in set (0.00 sec)mysql [localhost:5734] {root} (test) > select aes_decrypt(n,'test') from test where t = 1; +-----------------------+ | aes_decrypt(n,'test') | +-----------------------+ | b | +-----------------------+ 1 row in set (0.00 sec)

經過加密和壓縮的結果返回二進制字符,所以建議配置為VARBINARY或BLOB二進制字符串數據類型的列,防止字符集轉換從而導致插入失敗

mysql [localhost:5729] {msandbox} (test) > create table test (a int ,n varchar(60)); Query OK, 0 rows affected (0.06 sec)mysql [localhost:5729] {msandbox} (test) > insert into test values(1,AES_ENCRYPT('test','test')); ERROR 1366 (HY000): Incorrect string value: '\x87\xBD\x908\x85\x94...' for column 'name' at row 1mysql [localhost:5729] {msandbox} (test) > alter table test MODIFY `n` VARBINARY(180); Query OK, 0 rows affected (0.13 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql [localhost:5729] {msandbox} (test) > insert into test values(1,AES_ENCRYPT('test','test')); Query OK, 1 row affected (0.00 sec)mysql [localhost:5729] {msandbox} (test) > select a,AES_decrypt(n,'test') from test; +------+--------------------------+ | a | AES_decrypt(n,'test') | +------+--------------------------+ | 1 | test | +------+--------------------------+ 1 row in set (0.00 sec)mysql [localhost:5729] {msandbox} (test) > select * from test; +------+------------------+ | a | n | +------+------------------+ | 1 | ���8��;�h�c�� | +------+------------------+

避免插入失敗,也可以將值轉換為16進制,然后再進行存儲,查看的時候也需要先用 unhex 解析出來,然后再進行解密

mysql [localhost:5729] {msandbox} (test) > insert into test1 values(1,AES_ENCRYPT('test','test')); ERROR 1366 (HY000): Incorrect string value: '\x87\xBD\x908\x85\x94...' for column 'name' at row 1 mysql [localhost:5729] {msandbox} (test) > insert into test1 values(1,hex(AES_ENCRYPT('test','test'))); Query OK, 1 row affected (0.02 sec)mysql [localhost:5729] {msandbox} (test) > select AES_DECRYPT(unhex(n),'test') from test1-> ; +---------------------------------+ | AES_DECRYPT(unhex(n),'test') | +---------------------------------+ | test | +---------------------------------+ 1 row in set (0.00 sec)

加密方法示例

mysql [localhost:5729] {msandbox} (test) > SET block_encryption_mode = 'aes-256-cbc'; Query OK, 0 rows affected (0.00 sec)mysql [localhost:5729] {msandbox} (test) > SET @key_str = SHA2('mysql passphrase',512); Query OK, 0 rows affected (0.00 sec)mysql [localhost:5729] {msandbox} (test) > SET @init_vector = 'It is very very safe'; Query OK, 0 rows affected (0.00 sec)mysql [localhost:5729] {msandbox} (test) > SET @crypt_str = AES_ENCRYPT('test',@key_str,@init_vector); Query OK, 0 rows affected (0.00 sec)mysql [localhost:5729] {msandbox} (test) > SELECT AES_DECRYPT(@crypt_str,@key_str,@init_vector); +-----------------------------------------------+ | AES_DECRYPT(@crypt_str,@key_str,@init_vector) | +-----------------------------------------------+ | test | +-----------------------------------------------+ 1 row in set (0.00 sec)

結語

加密函數為 MySQL 原生的加密手段,可以加密一些類似于身份證、銀行卡等隱秘信息。業務中批量使用會造成一定的性能損耗,個人還是建議這些復雜的函數操作還是在應用層實現,降低數據庫的壓力。

總結

以上是生活随笔為你收集整理的技术分享 | 详解SQL加密函数:AES_ENCRYPT()的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。