六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

MySQL怎么使用AES_ENCRYPT()與AES_DECRYPT()進行加解密的示例

[摘要]MySQL中AES_ENCRYPT(密碼,鑰匙)函數可以對字段值做加密處理,AES_DECRYPT(表的字段名字,鑰匙)函數解密處理,下面這篇文章主要給大家介紹了關于MySQL利用AES_ENCRY...
MySQL中AES_ENCRYPT('密碼','鑰匙')函數可以對字段值做加密處理,AES_DECRYPT(表的字段名字,'鑰匙')函數解密處理,下面這篇文章主要給大家介紹了關于MySQL利用AES_ENCRYPT()與AES_DECRYPT()加解密的正確方法,文中給出了詳細的示例代碼,需要的朋友可以參考下。

前言

最近在工作中遇到一個需求是這樣的:需要在使用AES_ENCRYPT()函數將明文加密,存儲在MySQL中,但是遇到了一些問題……下面就來詳細介紹下。

說將加密后的密文,解密取出來是NULL。

看了一下,她發過來的表結構:

MySQL如何使用AES_ENCRYPT()與AES_DECRYPT()進行加解密的示例

再看了她通過AES_DECRYPT()函數加密了一個字符串,然后insert進去了,執行成功后,顯示了一個warning:

Query OK, 1 row affected, 1 warning (0.00 sec)

(沒有報錯而是warning,大概是sql_mode的緣故)

此時她忽略了這個warning,再通過AES_DECRYPT()解密后,發現取出來的明文為NULL。

再回看表結構,發現其字段屬性為“varchar” && 字符集是ut8,檢查warning為下:

mysql> show warnings;
+---------+------+------------------------------------------------------------------------+
  Level   Code   Message         
+---------+------+------------------------------------------------------------------------+
  Warning   1366   Incorrect string value: '\xE3f767\x12...' for column 'passwd' at row 1  
+---------+------+------------------------------------------------------------------------+
1 row in set (0.00 sec)

查了一下文檔,看一下這兩個函數的使用:

-- 將'hello world'加密,密鑰為'key',加密后的串存在@pass中
mysql> SET @pass=AES_ENCRYPT('hello world', 'key'); 
Query OK, 0 rows affected (0.00 sec)

-- 看一下加密后串的長度(都為2的整數次方)
mysql> SELECT CHAR_LENGTH(@pass);
+--------------------+
  CHAR_LENGTH(@pass)  
+--------------------+
  16    
+--------------------+
1 row in set (0.00 sec)

-- 使用AES_DECRYPT()解密
mysql> SELECT AES_DECRYPT(@pass, 'key');
+---------------------------+
  AES_DECRYPT(@pass, 'key')  
+---------------------------+
  hello world   
+---------------------------+
1 row in set (0.00 sec)

那么到底該如何存呢?

方法①:

將字段屬性設置為varbinary/binary/四個blob類型,等二進制字段屬性。

創建三個字段,屬性分別為varbinary、binary、blob。

并將'明文1','text2','明文_text3'加密,密鑰為key,存入表中。

最后取出。

mysql> CREATE TABLE t_passwd (pass1 varbinary(16), pass2 binary(16), pass3 blob);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO t_passwd VALUES (AES_ENCRYPT('明文1', 'key'), AES_ENCRYPT('text2', 'key'), AES_ENCRYPT('明文_text3', 'key')); 
Query OK, 1 row affected (0.01 sec)
mysql> SELECT AES_DECRYPT(pass1, 'key'), AES_DECRYPT(pass2, 'key'), AES_DECRYPT(pass3, 'key') FROM t_passwd;
+---------------------------+---------------------------+---------------------------+
  AES_DECRYPT(pass1, 'key')   AES_DECRYPT(pass2, 'key')   AES_DECRYPT(pass3, 'key')  
+---------------------------+---------------------------+---------------------------+
  明文1     text2     明文_text3    
+---------------------------+---------------------------+---------------------------+
1 row in set (0.00 sec)

當然,屬性括號內的長度要取決于明文的長度,此處明文較短,故只給了16。

方法②:

將密文十六進制化,再存入varchar/char列。

此處需要用到HEX()來存入,用UNHEX()取出。

創建一個字符串屬性的字段。

將'hello world'先用密鑰'key2'進行AES加密,再將加密后的串通過HEX函數十六進制化。

最后先將加密后的串通過UNHEX取出,再通過AES據密鑰'key2'解密:

mysql> CREATE TABLE t_passwd_2(pass1 char(32));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO t_passwd_2 VALUES (HEX(AES_ENCRYPT('hello world', 'key2')));
Query OK, 1 row affected (0.00 sec)
mysql> SELECT AES_DECRYPT(UNHEX(pass1), 'key2') FROM t_passwd_2; 
+-----------------------------------+
  AES_DECRYPT(UNHEX(pass1), 'key2')  
+-----------------------------------+
  hello world    
+-----------------------------------+
1 row in set (0.00 sec)

同樣,根據明文的長度不同,AES_ENCRYPT加密后的串長度也會有所變化,所以HEX后的字符串長度也會有所變化。
實際使用時,需要據業務評估出一個合理值即可。

方法③:

直接存入varchar中,不做十六進制化。

回溯到問題的一開始,將加密后的串,存到utf8字符集并且屬性為varchar中,是不行的。

實際上,將字符集改成latin1就可以了:

在insert的時候也不會報warning了。

mysql> CREATE TABLE t_passwd_3(pass varchar(32)) CHARSET latin1;
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO t_passwd_3 SELECT AES_ENCRYPT('text', 'key3');
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql> SELECT AES_DECRYPT(pass, 'key3') FROM t_passwd_3;
+---------------------------+
  AES_DECRYPT(pass, 'key3')  
+---------------------------+
  text    
+---------------------------+
1 row in set (0.00 sec)

這樣的方法雖然美,只需將字段字符集設置為latin1就可以了,但可能會帶來隱患:

文檔上寫了這樣的一句:

Many encryption and compression functions return strings for which the result might contain arbitrary byte values. If you want to store these results, use a column with a VARBINARY or BLOB binary string data type. This will avoid potential problems with trailing space removal or character set conversion that would change data values, such as may occur if you use a nonbinary string data type (CHAR, VARCHAR, TEXT).

大意是,如果用方法③那樣,直接將加密后的串存入char/varchar/text類型中,在做字符轉換的時或空格被刪除時,可能會帶來潛在的影響。

所以如果一定要存在char/varchar/text中,那么還是參考方法②,十六進制化一下吧。

或者如同方法①,直接存在二進制字段中。

總結

以上就是MySQL如何使用AES_ENCRYPT()與AES_DECRYPT()進行加解密的示例的詳細內容,更多請關注php中文網其它相關文章!


學習教程快速掌握從入門到精通的SQL知識。




主站蜘蛛池模板: 三级黄色在线视频中文 | 在线观看亚洲国产 | 四虎永久在线观看视频精品 | 四虎影视站长工具 | 天堂8中文在线 | 色综合天天射 | 色吧久久 | 日韩精品导航 | 天天躁日日躁狠狠躁黑人躁 | 天天擦天天干 | 日本高清在线观看视频你懂的 | 香蕉中文在线 | 特别黄的免费视频大片 | 最新在线精品国自产拍网站 | 综合色天天 | 中文字幕在线免费观看视频 | 人人干人人上 | 日韩欧美在线视频观看 | 伊人精品在线 | 伊人网在线视频观看 | 中文学幕专区 | 亚洲国产天堂久久综合图区 | 中国国产一级毛片视频 | 新天堂网| 五月欧美| 天天躁狠狠躁夜躁2021 | 青青草原免费在线观看视频 | 色婷婷中文字幕在线一区天堂 | 日韩三级在线观看 | 在线观看中文字幕第一页 | 亚洲激情另类小说 | 四虎免费永久在线播放 | 视频在线观看免费网址 | 日韩精品亚洲人成在线播放 | 日日干日日| 日韩欧美黄色片 | 天天干天天添 | 日日摸日日添日日透 | 日韩精品一二三区 | 最近更新免费中文字幕大全 | 日本高清视频在线的 |