欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

MySQL利用AES_ENCRYPT()與AES_DECRYPT()加解密的正確方法示例

 更新時(shí)間:2017年08月22日 09:02:17   作者:神諭丶  
MySQL中AES_ENCRYPT('密碼','鑰匙')函數(shù)可以對(duì)字段值做加密處理,AES_DECRYPT(表的字段名字,'鑰匙')函數(shù)解密處理,下面這篇文章主要給大家介紹了關(guān)于MySQL利用AES_ENCRYPT()與AES_DECRYPT()加解密的正確方法,文中給出了詳細(xì)的示例代碼,需要的朋友可以參考下。

前言

最近在工作中遇到一個(gè)需求是這樣的:需要在使用AES_ENCRYPT()函數(shù)將明文加密,存儲(chǔ)在MySQL中,但是遇到了一些問(wèn)題……下面就來(lái)詳細(xì)介紹下。

說(shuō)將加密后的密文,解密取出來(lái)是NULL。

看了一下,她發(fā)過(guò)來(lái)的表結(jié)構(gòu):

再看了她通過(guò)AES_DECRYPT()函數(shù)加密了一個(gè)字符串,然后insert進(jìn)去了,執(zhí)行成功后,顯示了一個(gè)warning:
Query OK, 1 row affected, 1 warning (0.00 sec)

(沒(méi)有報(bào)錯(cuò)而是warning,大概是sql_mode的緣故)

此時(shí)她忽略了這個(gè)warning,再通過(guò)AES_DECRYPT()解密后,發(fā)現(xiàn)取出來(lái)的明文為NULL。

再回看表結(jié)構(gòu),發(fā)現(xiàn)其字段屬性為“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)

查了一下文檔,看一下這兩個(gè)函數(shù)的使用:

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

-- 看一下加密后串的長(zhǎng)度(都為2的整數(shù)次方)
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)

那么到底該如何存呢?

方法①:

將字段屬性設(shè)置為varbinary/binary/四個(gè)blob類型,等二進(jìn)制字段屬性。

創(chuàng)建三個(gè)字段,屬性分別為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)

當(dāng)然,屬性括號(hào)內(nèi)的長(zhǎng)度要取決于明文的長(zhǎng)度,此處明文較短,故只給了16。

方法②:

將密文十六進(jìn)制化,再存入varchar/char列。

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

創(chuàng)建一個(gè)字符串屬性的字段。

將'hello world'先用密鑰'key2'進(jìn)行AES加密,再將加密后的串通過(guò)HEX函數(shù)十六進(jìn)制化。

最后先將加密后的串通過(guò)UNHEX取出,再通過(guò)AES據(jù)密鑰'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)

同樣,根據(jù)明文的長(zhǎng)度不同,AES_ENCRYPT加密后的串長(zhǎng)度也會(huì)有所變化,所以HEX后的字符串長(zhǎng)度也會(huì)有所變化。
實(shí)際使用時(shí),需要據(jù)業(yè)務(wù)評(píng)估出一個(gè)合理值即可。

方法③:

直接存入varchar中,不做十六進(jìn)制化。

回溯到問(wèn)題的一開(kāi)始,將加密后的串,存到utf8字符集并且屬性為varchar中,是不行的。

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

在insert的時(shí)候也不會(huì)報(bào)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)

這樣的方法雖然美,只需將字段字符集設(shè)置為latin1就可以了,但可能會(huì)帶來(lái)隱患:

文檔上寫(xiě)了這樣的一句:

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類型中,在做字符轉(zhuǎn)換的時(shí)或空格被刪除時(shí),可能會(huì)帶來(lái)潛在的影響。

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

或者如同方法①,直接存在二進(jìn)制字段中。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。

參考文檔:

Chapter 12 Functions and Operators - 12.13 Encryption and Compression Functions

相關(guān)文章

  • MySQL的線程池原理學(xué)習(xí)教程

    MySQL的線程池原理學(xué)習(xí)教程

    這篇文章主要介紹了MySQL的線程池原理學(xué)習(xí)教程,包括線程池的函數(shù)調(diào)用與關(guān)鍵接口等重要知識(shí),非常推薦!需要的朋友可以參考下
    2015-11-11
  • MySQL中describe命令的使用方法小結(jié)

    MySQL中describe命令的使用方法小結(jié)

    這篇文章主要介紹了MySQL中describe命令的使用方法小結(jié),describe命令主要用于獲取表或列等的各種信息,需要的朋友可以參考下
    2015-12-12
  • mysql 8.0.21免安裝版配置方法圖文教程

    mysql 8.0.21免安裝版配置方法圖文教程

    這篇文章主要為大家詳細(xì)介紹了mysql 8.0.21免安裝版配置教程,文中安裝步驟介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-07-07
  • MySQL基礎(chǔ)入門(mén)教程之事務(wù)

    MySQL基礎(chǔ)入門(mén)教程之事務(wù)

    事務(wù)主要用于處理操作量大,復(fù)雜度高的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于MySQL基礎(chǔ)入門(mén)教程之事務(wù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • MySQL優(yōu)化之如何寫(xiě)出高質(zhì)量sql語(yǔ)句

    MySQL優(yōu)化之如何寫(xiě)出高質(zhì)量sql語(yǔ)句

    在數(shù)據(jù)庫(kù)日常維護(hù)中,最常做的事情就是SQL語(yǔ)句優(yōu)化,因?yàn)檫@個(gè)才是影響性能的最主要因素。這篇文章主要給大家介紹了關(guān)于MySQL優(yōu)化之如何寫(xiě)出高質(zhì)量sql語(yǔ)句的相關(guān)資料,需要的朋友可以參考下
    2021-05-05
  • MySQL分組排序取每組第一條數(shù)據(jù)的實(shí)現(xiàn)

    MySQL分組排序取每組第一條數(shù)據(jù)的實(shí)現(xiàn)

    最近有個(gè)需求MySQL根據(jù)某一個(gè)字段分組,然后組內(nèi)排序,最后每組取排序后的第一條數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • 驗(yàn)證mysql是否安裝成功的方法

    驗(yàn)證mysql是否安裝成功的方法

    在本篇文章里小編給大家分享的是關(guān)于驗(yàn)證mysql是否安裝成功的方法,需要的朋友們可以學(xué)習(xí)下。
    2020-06-06
  • MySQL隱式類型轉(zhuǎn)換導(dǎo)致索引失效的解決

    MySQL隱式類型轉(zhuǎn)換導(dǎo)致索引失效的解決

    本文主要介紹了MySQL隱式類型轉(zhuǎn)換導(dǎo)致索引失效的解決,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • MySQL中數(shù)據(jù)查詢語(yǔ)句整理大全

    MySQL中數(shù)據(jù)查詢語(yǔ)句整理大全

    查詢語(yǔ)句是以后在工作中使用最多也是最復(fù)雜的用法,如何精準(zhǔn)的查詢出想要的結(jié)果以及用最合理的邏輯去查詢尤為重要,下面這篇文章主要給大家介紹了關(guān)于MySQL中數(shù)據(jù)查詢語(yǔ)句的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • Scott?數(shù)據(jù)?映射?MySQL代碼實(shí)現(xiàn)分享

    Scott?數(shù)據(jù)?映射?MySQL代碼實(shí)現(xiàn)分享

    這篇文章主要介紹了Scott?數(shù)據(jù)?映射?MySQL,文章圍繞Scott?數(shù)據(jù)?映射?MySQL的相關(guān)代碼分享給大家,具有一定的參考價(jià)值,需要的小伙伴可以參考一下,希望對(duì)你的學(xué)習(xí)有所幫助
    2022-02-02

最新評(píng)論