Heim  >  Artikel  >  Datenbank  >  Beispiel dafür, wie MySQL AES_ENCRYPT() und AES_DECRYPT() zur Ver- und Entschlüsselung verwendet

Beispiel dafür, wie MySQL AES_ENCRYPT() und AES_DECRYPT() zur Ver- und Entschlüsselung verwendet

黄舟
黄舟Original
2018-05-18 16:55:462892Durchsuche

Die Funktion AES_ENCRYPT („Passwort“, „Schlüssel“) in MySQL kann Feldwerte verschlüsseln, und die Funktion AES_DECRYPT (Feldname der Tabelle, „Schlüssel“) kann den Wert entschlüsseln MySQL Die richtige Methode zur Verschlüsselung und Entschlüsselung mit AES_ENCRYPT() und AES_DECRYPT() finden Sie im Artikel.

Vorwort

Ich bin kürzlich bei der Arbeit auf eine Anforderung wie diese gestoßen: Ich muss die Funktion AES_ENCRYPT() verwenden, um den Klartext zu verschlüsseln und zu speichern Es ist in MySQL verfügbar, es sind jedoch einige Probleme aufgetreten ... Lassen Sie uns es unten im Detail vorstellen.

Es heißt, dass der verschlüsselte Chiffretext nach der Entschlüsselung NULL sein wird.

Sah sich die Tabellenstruktur an, die sie gesendet hatte:

Nachdem sie sich die Struktur angesehen hatte, verschlüsselte sie eine mit der Funktionszeichenfolge AES_DECRYPT() , und fügen Sie es dann ein. warning:<br>

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

wird angezeigt (kein Fehler, aber Warnung, wahrscheinlich wegen sql_mode)

Diese Warnung wurde ignoriert Damals und nachdem sie es mit AES_DECRYPT() entschlüsselt hatte, stellte sie fest, dass der herausgenommene Klartext NULL war.

Beim Rückblick auf die Tabellenstruktur haben wir festgestellt, dass das Feldattribut „varchar“ && und der Zeichensatz ut8 ist. Die Warnung lautet wie folgt:

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

Überprüfen Sie die Dokumentation und werfen Sie einen Blick auf die Verwendung dieser beiden Funktionen:

-- 将&#39;hello world&#39;加密,密钥为&#39;key&#39;,加密后的串存在@pass中
mysql> SET @pass=AES_ENCRYPT(&#39;hello world&#39;, &#39;key&#39;); 
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, &#39;key&#39;);
+---------------------------+
| AES_DECRYPT(@pass, &#39;key&#39;) |
+---------------------------+
| hello world  |
+---------------------------+
1 row in set (0.00 sec)

Wie speichert man es also?

Methode ①:

Setzen Sie die Feldattribute auf varbinary/binary/vier Blob-Typen und andere binäre Feldattribute.

Erstellen Sie drei Felder mit den Attributen „varbinary“, „binary“ und „blob“.

Verschlüsseln Sie „plaintext1“, „text2“, „plaintext_text3“ mit dem Schlüssel und speichern Sie sie in der Tabelle.

Nehmen Sie es zuletzt heraus.

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(&#39;明文1&#39;, &#39;key&#39;), AES_ENCRYPT(&#39;text2&#39;, &#39;key&#39;), AES_ENCRYPT(&#39;明文_text3&#39;, &#39;key&#39;)); 
Query OK, 1 row affected (0.01 sec)
mysql> SELECT AES_DECRYPT(pass1, &#39;key&#39;), AES_DECRYPT(pass2, &#39;key&#39;), AES_DECRYPT(pass3, &#39;key&#39;) FROM t_passwd;
+---------------------------+---------------------------+---------------------------+
| AES_DECRYPT(pass1, &#39;key&#39;) | AES_DECRYPT(pass2, &#39;key&#39;) | AES_DECRYPT(pass3, &#39;key&#39;) |
+---------------------------+---------------------------+---------------------------+
| 明文1   | text2   | 明文_text3   |
+---------------------------+---------------------------+---------------------------+
1 row in set (0.00 sec)

Die Länge in den Attributklammern hängt natürlich von der Länge des Klartextes ab. Der Klartext ist hier kürzer, daher wird nur 16 angegeben.

Methode ②:

Hexadezimalisieren Sie den Chiffretext und speichern Sie ihn in der Spalte varchar/char.

Hier müssen Sie HEX() zum Einzahlen und UNHEX() zum Abheben verwenden.

Erstellen Sie ein Feld mit einem String-Attribut.

Verschlüsseln Sie „Hallo Welt“ mit AES unter Verwendung des Schlüssels „key2“ und verhexen Sie dann die verschlüsselte Zeichenfolge über die HEX-Funktion.

Entnehmen Sie abschließend die verschlüsselte Zeichenfolge über UNHEX und entschlüsseln Sie sie dann über den AES-Schlüssel „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(&#39;hello world&#39;, &#39;key2&#39;)));
Query OK, 1 row affected (0.00 sec)
mysql> SELECT AES_DECRYPT(UNHEX(pass1), &#39;key2&#39;) FROM t_passwd_2; 
+-----------------------------------+
| AES_DECRYPT(UNHEX(pass1), &#39;key2&#39;) |
+-----------------------------------+
| hello world   |
+-----------------------------------+
1 row in set (0.00 sec)

In ähnlicher Weise gilt je nach Länge des Klartextes: AES_ENCRYPT-Verschlüsselung Die Länge der Zeichenfolge nach HEX ändert sich ebenfalls, sodass sich auch die Länge der Zeichenfolge nach HEX ändert.
Bei der tatsächlichen Nutzung muss ein angemessener Wert auf der Grundlage des Geschäfts ermittelt werden.

Methode ③:

wird ohne Hexadezimalkonvertierung direkt in Varchar gespeichert.

Um zum Anfang des Problems zurückzukehren: Es ist nicht möglich, die verschlüsselte Zeichenfolge im UTF8-Zeichensatz zu speichern und das Attribut ist varchar.

Ändern Sie einfach den Zeichensatz in latin1:

Die Warnung wird beim Einfügen nicht gemeldet.

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(&#39;text&#39;, &#39;key3&#39;);
Query OK, 1 row affected (0.00 sec)
Records: 1 Duplicates: 0 Warnings: 0

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

Obwohl diese Methode schön ist, muss sie nur den Feldzeichensatz auf latin1 setzen, aber sie kann versteckte Gefahren mit sich bringen:

Das Dokument sagt Folgendes: Ein Satz:

Viele Verschlüsselungs- und Komprimierungsfunktionen geben Zeichenfolgen zurück, deren Ergebnis beliebige Bytewerte enthalten kann. Wenn Sie diese Ergebnisse speichern möchten, verwenden Sie eine Spalte mit dem binären Zeichenfolgendatentyp VARBINARY oder BLOB Mögliche Probleme beim Entfernen von nachgestellten Leerzeichen oder bei der Zeichensatzkonvertierung, die Datenwerte ändern würden, wie sie beispielsweise auftreten können, wenn Sie einen nicht-binären Zeichenfolgendatentyp (CHAR, VARCHAR, TEXT) verwenden.

Das heißt, wenn Sie die verwenden Methode ③ Auf diese Weise kann das direkte Speichern der verschlüsselten Zeichenfolge im Typ char/varchar/text potenzielle Auswirkungen haben, wenn eine Zeichenkonvertierung durchgeführt wird oder Leerzeichen gelöscht werden.

Wenn es also in char/varchar/text gespeichert werden muss, dann beziehen Sie sich auf Methode ② und hexadezimalisieren Sie es.

Oder wie bei Methode ① direkt im Binärfeld speichern.

Zusammenfassung

Das obige ist der detaillierte Inhalt vonBeispiel dafür, wie MySQL AES_ENCRYPT() und AES_DECRYPT() zur Ver- und Entschlüsselung verwendet. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn