MySQL が暗号化と復号化に AES_ENCRYPT() と AES_DECRYPT() を使用する方法の例
MySQL の AES_ENCRYPT ('password', 'key') 関数はフィールド値を暗号化でき、AES_DECRYPT (テーブルのフィールド名、'key') 関数は値を復号化できます。次の記事では主に の使用方法を紹介します。 MySQL の AES_ENCRYPT() および AES_DECRYPT() の暗号化と復号化については、この記事に詳細なサンプル コードが記載されているので、必要な友人は参照してください。
前書き
私は最近仕事で要件に遭遇しました。AES_ENCRYPT()
関数を使用して平文を暗号化し、MySQL に保存する必要がありますが、いくつかの問題が発生しました。 . …以下で詳しく紹介していきます。 AES_ENCRYPT()
函数将明文加密,存储在MySQL中,但是遇到了一些问题……下面就来详细介绍下。
说将加密后的密文,解密取出来是NULL。
看了一下,她发过来的表结构:
再看了她通过AES_DECRYPT()函数加密了一个字符串,然后insert进去了,执行成功后,显示了一个warning:<br>
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()
もう一度見てみると、AES_DECRYPT() 関数を使用して文字列を暗号化し、挿入しました。実行が成功した後、 警告が表示されました。 </p>
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)
(エラーはありませんが、警告はあります。おそらく sql_mode が原因です)
この時点で、彼女は警告を無視し、AES_DECRYPT()
を通じて復号化したところ、取り出した平文はNULLです。 テーブル構造を振り返ると、そのフィールド属性が "varchar" && であり、文字セットが ut8 であることがわかりました。次のように警告を確認してください。これら 2 つの関数:
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)
属性 varbinary、binary、blob を持つ 3 つのフィールドを作成します。
「plaintext1」、「text2」、「plaintext_text3」を鍵keyで暗号化してテーブルに格納します。
最後に取り出してください。rrreee
もちろん、属性括弧内の長さは平文の長さに依存します。ここでは平文の方が短いため、16 だけが与えられます。
方法②:
暗号文を16進数に変換し、varchar/char列に格納します。 🎜🎜🎜ここでは、入金には HEX() を使用し、出金にはUNHEX()
を使用する必要があります。 🎜🎜文字列属性を持つフィールドを作成します。 🎜🎜🎜キー「key2」を使用して「hello world」を AES で暗号化し、HEX 関数を使用して暗号化された文字列を 16 進数化します。 🎜🎜🎜最後に、UNHEXで暗号化文字列を取り出し、AESキー「key2」で復号化します: 🎜rrreee🎜同様に、平文の長さに応じて、AES_ENCRYPT暗号化文字列の長さも変わるため、HEX後続の文字列の長さも変わります。 🎜実際の使用においては、業務に応じて妥当な値を評価する必要があります。 🎜🎜🎜🎜🎜方法③: 🎜🎜🎜🎜🎜16進数変換せずにvarcharに直接保存します。 🎜🎜問題の最初に戻ると、暗号化された文字列を utf8 文字セットに保存することはできず、属性は varchar です。 🎜🎜実際には、文字セットを latin1 に変更するだけです: 🎜🎜🎜挿入時に警告は報告されません。 🎜rrreee🎜このメソッドは美しいですが、必要なのはフィールドの文字セットを latin1 に設定するだけですが、隠れた危険をもたらす可能性があります: 🎜🎜🎜ドキュメントには次の文が書かれています: 🎜🎜🎜多くの暗号化および圧縮関数は、結果には任意のバイト値が含まれる可能性があります。これらの結果を格納する場合は、VARBINARY または BLOB バイナリ文字列データ型の列を使用します。これにより、データ値が変更される可能性がある、末尾のスペースの削除や文字セット変換による潜在的な問題が回避されます。非バイナリ文字列データ型 (CHAR、VARCHAR、TEXT) を使用する場合、一般的な考え方は、③の方法を使用する場合、暗号化された文字列を char/varchar/text 型に直接格納してから文字を作成するということです。変換時または空白文字の削除時に潜在的な影響が生じます。 🎜🎜そのため、char/varchar/textに格納する必要がある場合は、方法②を参照して16進数化してください。 🎜🎜🎜または、方法①と同様に、バイナリフィールドに直接格納します。 🎜🎜🎜🎜概要🎜🎜🎜以上がMySQL が暗号化と復号化に AES_ENCRYPT() と AES_DECRYPT() を使用する方法の例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック











ビッグ データ構造の処理スキル: チャンキング: データ セットを分割してチャンクに処理し、メモリ消費を削減します。ジェネレーター: データ セット全体をロードせずにデータ項目を 1 つずつ生成します。無制限のデータ セットに適しています。ストリーミング: ファイルやクエリ結果を 1 行ずつ読み取ります。大きなファイルやリモート データに適しています。外部ストレージ: 非常に大規模なデータ セットの場合は、データをデータベースまたは NoSQL に保存します。

MySQL クエリのパフォーマンスは、検索時間を線形の複雑さから対数の複雑さまで短縮するインデックスを構築することで最適化できます。 PreparedStatement を使用して SQL インジェクションを防止し、クエリのパフォーマンスを向上させます。クエリ結果を制限し、サーバーによって処理されるデータ量を削減します。適切な結合タイプの使用、インデックスの作成、サブクエリの使用の検討など、結合クエリを最適化します。クエリを分析してボトルネックを特定し、キャッシュを使用してデータベースの負荷を軽減し、オーバーヘッドを最小限に抑えます。

PHP で MySQL データベースをバックアップおよび復元するには、次の手順を実行します。 データベースをバックアップします。 mysqldump コマンドを使用して、データベースを SQL ファイルにダンプします。データベースの復元: mysql コマンドを使用して、SQL ファイルからデータベースを復元します。

MySQLテーブルにデータを挿入するにはどうすればよいですか?データベースに接続する: mysqli を使用してデータベースへの接続を確立します。 SQL クエリを準備します。挿入する列と値を指定する INSERT ステートメントを作成します。クエリの実行: query() メソッドを使用して挿入クエリを実行します。成功すると、確認メッセージが出力されます。

MySQL 8.4 (2024 年時点の最新の LTS リリース) で導入された主な変更の 1 つは、「MySQL Native Password」プラグインがデフォルトで有効ではなくなったことです。さらに、MySQL 9.0 ではこのプラグインが完全に削除されています。 この変更は PHP および他のアプリに影響します

PHP で MySQL ストアド プロシージャを使用するには: PDO または MySQLi 拡張機能を使用して、MySQL データベースに接続します。ストアド プロシージャを呼び出すステートメントを準備します。ストアド プロシージャを実行します。結果セットを処理します (ストアド プロシージャが結果を返す場合)。データベース接続を閉じます。

PHP を使用して MySQL テーブルを作成するには、次の手順が必要です。 データベースに接続します。データベースが存在しない場合は作成します。データベースを選択します。テーブルを作成します。クエリを実行します。接続を閉じます。

Oracle データベースと MySQL はどちらもリレーショナル モデルに基づいたデータベースですが、Oracle は互換性、スケーラビリティ、データ型、セキュリティの点で優れており、MySQL は速度と柔軟性に重点を置いており、小規模から中規模のデータ セットに適しています。 ① Oracle は幅広いデータ型を提供し、② 高度なセキュリティ機能を提供し、③ エンタープライズレベルのアプリケーションに適しています。① MySQL は NoSQL データ型をサポートし、② セキュリティ対策が少なく、③ 小規模から中規模のアプリケーションに適しています。
