序文 最近、仕事で 暗号化された暗号文を復号すると、結果が NULL になると言われています。 彼女が送ってきたテーブル構造を見てみました。 次に、彼女が AES_DECRYPT() 関数を使用して文字列を暗号化し、それを挿入しているのを確認しました。実行が成功すると、 (エラーはありませんが、警告は出ます。おそらく sql_mode が原因です) このとき、彼女は警告を無視し、 テーブル構造をもう一度見てみると、フィールド属性は「varchar」であり、文字セットは ut8 であり、警告は次のようになります。 mysql> 警告を表示します。 +---------+------+------------------------------------------------------------------------------------+ | レベル | コード | メッセージ | +---------+------+------------------------------------------------------------------------------------+ | 警告 | 1366 | 行 1 の列 'passwd' の文字列値が正しくありません: '\xE3f767\x12...' | +---------+------+------------------------------------------------------------------------------------+ セット内の 1 行 (0.00 秒) ドキュメントをチェックして、これら 2 つの関数がどのように使用されるかを確認してください。 -- キー 'key' を使用して 'hello world' を暗号化し、暗号化された文字列を @passmysql> SET @pass=AES_ENCRYPT('hello world', 'key'); に保存します。 クエリは正常、影響を受けた行は 0 行 (0.00 秒) -- 暗号化された文字列の長さを確認します(すべて 2 の累乗です) mysql> CHAR_LENGTH(@pass)を選択します。 +--------------------+ | CHAR_LENGTH(@pass) | +--------------------+ | 16 | +--------------------+ セット内の 1 行 (0.00 秒) -- AES_DECRYPT() を使用して復号化します。mysql> SELECT AES_DECRYPT(@pass, 'key'); +---------------------------+ | AES_DECRYPT(@pass, 'キー') | +---------------------------+ | こんにちは世界 | +---------------------------+ セット内の 1 行 (0.00 秒) それでどうやって保存するのでしょうか? 方法1: フィールド プロパティを varbinary/binary/four blob 型に設定し、その他のバイナリ フィールド プロパティを設定します。 varbinary、binary、blob の属性を持つ 3 つのフィールドを作成します。 そして、キー key を使用して 'plaintext1'、 'text2'、 'plaintext_text3' を暗号化し、テーブルに保存します。 最後に取り出します。 mysql> テーブル t_passwd を作成します (pass1 varbinary(16), pass2 binary(16), pass3 blob); クエリは正常、影響を受けた行は 0 行 (0.00 秒) mysql> t_passwd に値 (AES_ENCRYPT('plaintext1', 'key'), AES_ENCRYPT('text2', 'key'), AES_ENCRYPT('plaintext_text3', 'key')) を挿入します。 クエリは正常、1 行が影響を受けました (0.01 秒) mysql> t_passwd から AES_DECRYPT(pass1, 'キー')、AES_DECRYPT(pass2, 'キー')、AES_DECRYPT(pass3, 'キー') を選択します。 +---------------------------+----------------------------+---------------------------+ | AES_DECRYPT(pass1, 'キー') | AES_DECRYPT(pass2, 'キー') | AES_DECRYPT(pass3, 'キー') | +---------------------------+----------------------------+---------------------------+ | プレーンテキスト1 | テキスト2 | プレーンテキスト3 | +---------------------------+---------------------------+---------------------------+ セット内の 1 行 (0.00 秒) もちろん、属性括弧の長さはプレーンテキストの長さによって異なります。ここではプレーンテキストの方が短いため、16 のみが与えられています。 方法2: 暗号文を 16 進数に変換し、varchar/char 列に保存します。 ここでは、入金には HEX() を使用し、出金には 文字列属性を持つフィールドを作成します。 まず、AES を使用してキー「key2」で「hello world」を暗号化し、次に HEX 関数を使用して暗号化された文字列を 16 進数に変換します。 最後に、暗号化された文字列は UNHEX を通じて取り出され、キー「key2」に従って AES を通じて復号化されます。 mysql> テーブル t_passwd_2(pass1 char(32)) を作成します。 クエリは正常、影響を受けた行は 0 行 (0.01 秒) mysql> t_passwd_2 に値 (HEX(AES_ENCRYPT('hello world', 'key2')) を挿入します); クエリは正常、1 行が影響を受けました (0.00 秒) mysql> t_passwd_2 から AES_DECRYPT(UNHEX(pass1), 'key2') を選択します。 +-----------------------------------+ | AES_DECRYPT(UNHEX(pass1), 'key2') | +-----------------------------------+ | こんにちは世界 | +-----------------------------------+ セット内の 1 行 (0.00 秒) 同様に、平文の長さに応じて、AES_ENCRYPT で暗号化された文字列の長さも変化するため、HEX 以降の文字列の長さも変化します。 方法3: 16 進数化せずに varchar に直接保存します。 問題の始まりに戻ると、暗号化された文字列を utf8 文字セットで保存することはできず、属性は varchar です。 実際には、文字セットを latin1 に変更するだけです。 挿入中に警告は報告されません。 mysql> CREATE TABLE t_passwd_3(pass varchar(32)) CHARSET latin1; クエリは正常、影響を受けた行は 0 行 (0.00 秒) mysql> t_passwd_3 に INSERT INTO し、AES_ENCRYPT('text', 'key3') を選択します。 クエリは正常、1 行が影響を受けました (0.00 秒) 記録: 1 重複: 0 警告: 0 mysql> t_passwd_3 から AES_DECRYPT(pass, 'key3') を選択します。 +---------------------------+ | AES_DECRYPT(pass, 'key3') | +---------------------------+ | テキスト | +---------------------------+ セット内の 1 行 (0.00 秒) この方法は美しいですが、フィールドの文字セットを latin1 に設定すると、隠れた危険が生じる可能性があります。 文書にはこう記されている。 多くの暗号化および圧縮関数は、結果に任意のバイト値が含まれる可能性がある文字列を返します。これらの結果を保存する場合は、VARBINARY または BLOB バイナリ文字列データ型の列を使用します。これにより、非バイナリ文字列データ型 (CHAR、VARCHAR、TEXT) を使用する場合に発生する可能性がある、末尾のスペースの削除やデータ値を変更する文字セット変換に関する潜在的な問題を回避できます。 一般的な考え方としては、方法 3 を使用して暗号化された文字列を char/varchar/text 型に直接保存すると、文字変換を実行するときやスペースを削除するときに潜在的な影響が出る可能性があります。 したがって、char/varchar/text で保存する必要がある場合は、方法 ② を参照して 16 進数に変換します。 または、方法①のようにバイナリフィールドに直接格納します。 要約する 上記はこの記事の全内容です。この記事の内容が皆さんの勉強や仕事に少しでもお役に立てれば幸いです。ご質問があれば、メッセージを残してコミュニケーションしてください。123WORDPRESS.COM をご愛顧いただき、ありがとうございます。 参考資料: 第 12 章 関数と演算子 - 12.13 暗号化と圧縮関数 以下もご興味があるかもしれません:
|
<<: 複数のネットワークカードを備えた Linux システムでのルーティング構成の詳細な説明
>>: JavaScriptのプロトタイプオブジェクトを徹底的に理解しましょう
antd-mobileをインストールするグローバル輸入 npm をインストール antd-mobil...
1 yumでソフトウェアをインストールしたときにダウンロードしたrpmパッケージを保存しますyum ...
1. システム環境[root@localhost ホーム]# cat /etc/redhat-re...
不明な点があるときはいつでも、Blog Park にアクセスして、いつでも答えやインスピレーションを...
目次1. NFS-Ganeshaの紹介2. NFS-Ganeshaの設定3. NFS-Ganesha...
絶対位置決め方式: (1)親要素を相対配置に設定します。親要素の高さを指定しない場合は、左の子要素の...
1. OpenSSL公式サイト公式ダウンロードアドレス: https://www.openssl....
目次1. プロジェクト統合1. CDNインポート方法: 2. 箱の梱包を確認する3. 迅速な箱詰め4...
Vue の紹介現在のビッグフロントエンドの時代は、混乱と衝突の時代です。世界は多くの派閥に分かれてお...
序文React 16から、子コンポーネントで発生したエラーを捕捉し、エラーログを記録し、ダウングレー...
1. コマンドの紹介時間は、コマンドの実行に費やされた時間や関連するシステム リソース、その他の情報...
gdb を使用してカーネル シンボルをロードする arm-eabi-gdb 出力/ターゲット/製品/...
目次概要意味インスタンスメソッドプリミティブ型とインスタンスオブジェクト間の自動変換カスタムメソッド...
目次序文非同期イテレータとは何ですか?非同期イテレータストリームとしてページング機能を備えたAPIの...
実装方法は3つのステップに分かれています。テンプレートに 2 つのボタンを設定し、v-if と v-...