AES_ENCRYPTされた文字列の曖昧検索をしたいと思っています。AES_ENCRYPTで暗号化した文字列をBLOB型のフィールドに書き込んでいますが、SELECT文で文字列を抽出時、完全に一致する文字列しか抽出できません。
テーブル名:
member
フィールド名:
id blob
name blob
email blob
テーブルに登録されている文字列:
id name email
----------------------------------------
0001, dokumori, dm@example.com
0002, blahblah, blah@example.com
0003, dokublah, db@example.com
(上記は全てAES_ENCRYPTされているものとします)
そして、以下のコマンドを走らせても、該当が見つかりません:
SELECT * FROM member WHERE name LIKE AES_ENCRYPT ('%doku%','password');
以下のようにすると、当然ですが、該当するレコードは表示されます:
SELECT * FROM member WHERE name = AES_ENCRYPT ('dokumori','password');
AES_ENCRYPTに関しては、文献自体が少ないようで、なかなか答えが見つかりません。この件に関してもしご存じでしたらアドバイスをお願いします。
No.2ベストアンサー
- 回答日時:
こんにちは。
すみません、私の勘違いのようでした・・・。
この式の場合のポイントは、
「'dokumori'をENCRYPTしたものと'%doku%'をENCRYPTしたものが、果たしてLIKEで拾えるか?」
というところですね。
そこでAES_ENCRYPTについて調べてみました・・・。
AES はブロックレベルのアルゴリズムであるため、不揃いの長さの文字列のエンコード時には埋め込みが行われる。したがって、結果の文字列の長さは 16*(trunc(string_length/16)+1) として計算することができる。
とありました・・・。
「doku」をAES_ENCRYPTした結果と、「dokumori」をAES_ENCRYPTした結果が、前方ビットが同じであるなら、
SELECT * FROM member WHERE name LIKE CONCAT('%', AES_ENCRYPT('doku', 'password'));
で、前方一致検索はできそうですが、
実際のデータは'dokumoriXXXXXXXX'を暗号化したもの。
検索条件が'dokuXXXXXXXXXXXX'を暗号化したもの。
のような感じで、16ビットを一括りとして変換してそうなので、まったく違う結果になってそうです・・・。
(推測ばっかりですみません・・・)
1文字ずつ暗号化しているのならできそうなんですが・・・。
お役に立てずにすみません・・・。
(^^ゞ
ご回答有り難うございました。お返事遅れて申し訳ありません。
なるほど、埋め込みとはそういう意味だったのか。。。
確かに、埋め込み+暗号化した文字列をマッチしようとしている訳ですから、マッチし得ないですね。仰るとおりだと思います。
まず、暗号化されたレコードたちを復号化して一時テーブルにはき出した後、ふつうにSELECTで抽出するのが、おそらく一番楽な方法ですね。
先月中頃から悩み続けていたのですが、ようやくすっきりしました。有り難うございました。
No.1
- 回答日時:
こんにちは。
このSQLでは、LIKEの前にAES_ENCRYPT ('%doku%','password')が評価されていると思いますが・・・?
'%doku%'というキー(%も含んで文字列)では、該当する'password'が見つからなかった。
よって、AES_ENCRYPT関数の戻り値はNULL。
LIKE NULLは当然・・・ですよね?
(^^ゞ
この回答への補足
taka451213さん、コメントありがとうございます。
"LIKE"の代わりに"=" を使い、検索文字列を"%"で囲まない時には検索が成功するので、LIKEを利用した際の特殊な文法上のルールがあるか、またはLIKE自体が使えないのではないかと思っています。前者であることを望みつつ質問させていただいてます。
なお、"password"というのは、encrypt時に設定するパスワード文字列であり、検索対象ではありません。
AES_ENCRYPTを用いる場合、DBへの書き込みは:
INSERT INTO member (id, name, email) values AES_ENCRYPT('0001','password'), AES_ENCRYPT('dokumori','password'), AES_ENCRYPT(dm@example.com','password');
というようなSQLを使って行います。
そして暗号化->バイナリ化された文字列を検索する際、キーワードを暗号化した上でマッチさせるため:
...AES_ENCRYPT ('doku','password')
としています。AES_ENCRYPTで暗号化せずに検索した場合、stringとbinaryがマッチし得ないため、望むような結果が表示されません。
ということで、ご指摘頂いた部分が原因ではないと思っていますが、如何でしょう?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Excel(エクセル) PHPプログラムをエクセルに張り付けると検索ボックスがでてくる! 3 2022/05/08 07:10
- Access(アクセス) アクセス where句を使用して複数条件抽出をするには 2 2022/08/29 13:24
- PHP コメント機能に返信欄を矢印で追加したい 1 2022/05/09 21:17
- Oracle sqlで質問です。 aテーブルとbテーブルがあり、下記のsqlで取得したidとnameに一致しないレ 1 2022/04/20 20:34
- その他(データベース) Accessのクエリで1フィールドの抽出条件設定をNullでなく全角半角含む空白のみの文字列でない文 1 2023/04/24 15:20
- PHP 重複を防ぐ記述について教えて下さい。 3 2023/04/03 14:35
- SQL Server [SQLServer] テーブル名からカラム名を取得する 1 2022/08/23 21:20
- JavaScript フォームが空欄の時にフォームの外をクリックすると、エラーが出るコードを調べています。 1 2023/06/25 11:51
- SQL Server SQLについて質問です。 a表がありその表には従業員名を保存するname列があります。 LIKE演算 1 2022/05/17 17:49
- Oracle SQL update方法 2 2022/06/22 14:07
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
VIEWの元のテーブルのindexって...
-
insertを高速化させたい
-
副問合せの書き方について
-
SQL Left Join で重複を排除す...
-
ある条件の最大値+1を初番する...
-
selectした大量データをinsert...
-
マイクラPC版のコマンドで効率...
-
select文のwhere句に配列を入れ...
-
一つ前のレコードの値と減算し...
-
my_itemsテーブルのIDにAUTO_IN...
-
期間の重複を調べるSQL文につい...
-
1対多結合で多を絞り込み条件と...
-
SELECT~LIKE~の結果が変
-
1テーブル&複数レコードの更新...
-
MySQLにてCOUNTした値を更にCOUNT
-
エクセルの関数について教えて...
-
Unionした最後にGROUP BYを追加...
-
SQLサーバから、項目の属性(型...
-
バインド変数について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
SQL Left Join で重複を排除す...
-
VIEWの元のテーブルのindexって...
-
SQLサーバから、項目の属性(型...
-
select文のwhere句に配列を入れ...
-
副問合せの書き方について
-
マイクラPC版のコマンドで効率...
-
Unionした最後にGROUP BYを追加...
-
selectした大量データをinsert...
-
SQLにて特定の文字を除いた検索...
-
[SQLServer] テーブル名からカ...
-
1テーブル&複数レコードの更新...
-
inner joinをすると数がおかし...
-
クエリ表示と、ADOで抽出したレ...
-
ある条件の最大値+1を初番する...
-
sqlで、600行あるテーブルを100...
-
複数テーブルのGROUP BY の使い...
-
insertを高速化させたい
-
PL/SQLの変数について
-
キー毎の、ある列のmaxのレコー...
おすすめ情報