
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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
エクセルの関数について教えて...
-
SQL Left Join で重複を排除す...
-
マイクラPC版のコマンドで効率...
-
updateを1行ずつ実行したい。
-
selectで拾ってきたデータをも...
-
埼玉県の中央部の方!!
-
inner joinをすると数がおかし...
-
ローカルルーターモードとは
-
DB設計について
-
エクセルで最後の文字だけ置き...
-
イケメンにチーズバーガーをぶ...
-
MySQLで半角濁音文字の検索
-
入力値と外部キーをINSERTするには
-
URL と行番号の指定
-
Access VBAでのIDの自動発番
-
SQLの検索について
-
Mysql UPDATE出来ません
-
差し込み後、元データを変更し...
-
列番号による項目の取得について
-
noの後の語
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルで最後の文字だけ置き...
-
エクセルの関数について教えて...
-
VIEWの元のテーブルのindexって...
-
エラー 1068 (42000): 複数の主...
-
SQLサーバから、項目の属性(型...
-
select文のwhere句に配列を入れ...
-
SQL Left Join で重複を排除す...
-
Access パラメータクエリをcsv...
-
マイクラPC版のコマンドで効率...
-
【Transact-sql】 execの結果を...
-
sqlで、600行あるテーブルを100...
-
SQLにて特定の文字を除いた検索...
-
1テーブル&複数レコードの更新...
-
PL/SQLの変数について
-
WordpressのContact form 7でzi...
-
複数テーブルのGROUP BY の使い...
-
バインド変数について
-
inner joinをすると数がおかし...
-
MySQLのint型で001と表示する方...
-
updateを1行ずつ実行したい。
おすすめ情報