awaawaさん、こんばんは
ちょっと実現方法が悩ましいところですね。
外だしSQLやプロシージャなどのことを考えると、
どうやっても完璧なものにはならないので、
この辺のバランスを踏まえた機能化を考えてみると...
ひとまず、言えることは、
SQL上の関数やプロシージャを使う方法は、
確かにDBFluteがそこを抑えてしまっているので、
DBFlute側で何かしらアプローチしないといけないでしょう。
なので優先度としては、ここが一番高いところと言えそう。
TableSqlNameFilter ならぬ ColumnSqlNameFilter を追加すれば、
好きなように関数使ったりプロシージャ使ったりできるかな。
検索時は復号化、登録・更新時は暗号化ってできるように。
JavaのAPIの場合は、EntityのExクラスのgetter/setterに
フィルタ処理を入れるじゃダメなのかな?
dfpropで指定したとしても、結局やることはそういうことに
なるのであれば、あまり機能化する意味がないかなって。
2011/5/19 awaawa <p1us3i...@gmail.com>:
> --
> このメールは Google グループのグループ「DBFluteユーザの集い」の登録者に送られています。
> このグループに投稿するには、dbf...@googlegroups.com にメールを送信してください。
> このグループから退会するには、dbflute+u...@googlegroups.com にメールを送信してください。
> 詳細については、http://groups.google.com/group/dbflute?hl=ja からこのグループにアクセスしてください。
>
>
> TableSqlNameFilter ならぬ ColumnSqlNameFilter を追加すれば、
> 好きなように関数使ったりプロシージャ使ったりできるかな。
> 検索時は復号化、登録・更新時は暗号化ってできるように。
ああ、でも select句とwhere句では復号と暗号の
やりたいことが逆になるのか。
where 復号(foo.FOO_DATA) = 'plain'
でもつじつまは合うけど、やはりやりたいのは、
where foo.FOO_DATA = 暗号('plain')
だよね。
(ファンクションインデックスとか作りたくないし)
また、update 文とか insert 文もカラム名に対してではなく、
値に対して暗号化していかないとダメなので、
ColumnSqlNameFilterはそれはそれであっても良いけど、
暗号化・復号化の話では使えないや。
CBに関しては、条件付与するところやselect句の生成の
ロジックがほぼ決まったところにあるので比較的やりやすい
かな。でも、サブクエリとか色々なパターンで二重に復号化
されないようにとか考えると厳密な実現はかなり難しいことに
変わりはなさそう。
更新系に関しては、ロジックが結構散在しているので、
処理を洗い出さないとかなり難しいね。
ちなみに、実際に使うつもりなのかな?
2011/5/20 kubo <dbf...@gmail.com>:
> CBに関しては、条件付与するところやselect句の生成の
> ロジックがほぼ決まったところにあるので比較的やりやすい
> かな。でも、サブクエリとか色々なパターンで二重に復号化
> されないようにとか考えると厳密な実現はかなり難しいことに
> 変わりはなさそう。
逆だった。。。
意外にConditionBeanが一番難しい。
ひとまず、ポイントとなる処理をまとめました。
CB
-> AbstractSqlClause, ConditionKey
insert() / batchInsert()
-> TnInsertEntityDynamicCommand.createInsertSql()
update() / batchUpdate()
-> TnUpdateEntityDynamicCommand.createUpdateSql()
queryUpdate()
-> TnQueryUpdateDynamicCommand.buildQueryUpdateTwoWaySql()
queryDelete()
-> TnQueryDeleteDynamicCommand.buildQueryDeleteTwoWaySql()
queryInsert()
-> TnQueryInsertDynamicCommand.buildQueryInsertTwoWaySql()
で、仕様的に迷うのが queryInsert() で、
select部分に復号化を入れた方がいいのかない方がいいのか...
実装的には、復号化が入っちゃう方が簡単で、
ここだけ特別扱いで復号化しないって方が難しい。
2011/5/20 kubo <dbf...@gmail.com>:
>> 仕様的に迷うのが queryInsert() で、
>> select部分に復号化を入れた方がいいのかない方がいいのか...
>> 実装的には、復号化が入っちゃう方が簡単で、
>> ここだけ特別扱いで復号化しないって方が難しい。
> これはinsert先次第で動作が変わるかと。
> ・insert先のテーブルのカラム、selectのカラムがいずれも暗号化対象。
> →復号化しない。(復号化、暗号化になるため、処理打ち消し。)
> ・insert先のテーブルのカラムが暗号化対象、selectのカラムが暗号化対象外。
> →暗号化する。(基本ありえないと思いますが。)
> ・insert先のテーブルのカラムが暗号化対象外、selectのカラムが暗号化対象。
> →復号化する。(基本ありえないと思いますが。)
まあ、DB to DB だから暗号化も復号化もしないでそのままって感じかな。
暗号化するくらいのカラムだから、復号化して別のカラムに入れるって
考えにくいので。CBでselect句の復号化を suppress できるような仕組みに
できればいいかな...
一応、こんなイメージで作ろうかと思っています。
ひとまず、暗号化のSQL関数を想定して。
ただ、Javaクラス利用の拡張もできるような形で。
GearedCipher cipher = new GearedCipher();
cipher.addFunctionFilter(new CipherFunctionFilter() {
public String encrypt(String valueExp) {
return "AES_ENCRYPT(" + valueExp + ", 'foo')";
}
public String decrypt(String valueExp) {
return "AES_DECRYPT(" + valueExp + ", 'foo')";
}
});
DBFluteConfig config = DBFluteConfig.getInstance();
config.unlock();
config.setGearedCipher(cipher);
config.lock();
上記は MySQL の関数の例だけど、
そもそもOracleの暗号化の関数やプロシージャの特徴を
色々と教えてくれるとありがたい。(全く知らないので)
2011/5/21 awaawa <p1us3i...@gmail.com>:
ちょっと間違いがあった。
addFunctionFilter では対象カラムを指定します。
> cipher.addFunctionFilter(new CipherFunctionFilter() {
> public String encrypt(String valueExp) {
> return "AES_ENCRYPT(" + valueExp + ", 'foo')";
> }
ColumnInfo columnInfo = MemberDbm.getInstance().columnMemberName();
cipher.addFunctionFilter(columnInfo, new CipherFunctionFilter() {
public String encrypt(String valueExp) {
return "AES_ENCRYPT(" + valueExp + ", 'foo')";
}
...
2011/5/21 kubo <dbf...@gmail.com>:
awaawaです。
そのイメージであれば、
製造担当者が都度カラムの暗号復号化を意識しなくていいので、助かります。
※暗号化ハッシュの場合は、decryptでvalueExpをそのまま返せば大丈夫ですよね。
> そもそもOracleの暗号化の関数やプロシージャの特徴を
> 色々と教えてくれるとありがたい。(全く知らないので)
このサイトがわかりやすいかと思います。
不明点があれば、わかる範囲はすぐに回答します。
わからなければ調べますので、言ってください。
http://www.shift-the-oracle.com/plsql/dbms_crypto/encrypt-type.html
http://www.shift-the-oracle.com/plsql/dbms_crypto/encrypt-decrypt.html
11/05/21 kubo <dbf...@gmail.com>:
awaawaです。
ふと思ったのですが、
ReplaceSchemaのテストデータは暗号化された状態であるべきですよね。
それが正しい使用だと思うのですが、テストデータを管理する上で若干コストが気になります。
って、書きながらReplaceSchemaのドキュメントを読んでいたら、
take-finallyで解決しますね。これを使って大丈夫ですよね。
> データ登録後に実行したいSQL
> SQL関数でパスワードを暗号化する(データファイル上はplainで定義しておいて)
11/05/21 awaawa <p1us3i...@gmail.com>:
ReplaceSchemaはそんな感じです。
TakeFinallyさんが結構至る所で大活躍で。
DBFlute-0.9.8.4-00-SNAPSHOT にて実装してみました。
使い方は、dbflute-mysql-example の
ExtendedDBFluteInitializer をご覧下さい。
(このクラスは littleAdjustmentMap.dfprop で指定)
queryInsert() は、仕様上正当に対象外。これは恒常的に。
PKやFK、排他制御カラムなどは対象外(制限してるわけではないけど)。
varyingUpdate() の "set FOO = FOO + 1"においても対象外。
これも恒常的にかな。
(やるとなると復号化して足して暗号化してって...)
DerivedReferrerは、制限的に対象外。
ちょっと激むずで対応するかどうか不明な感じ。
まあ、sum、avg するようなカラムに暗号化かける
ことは相当にめったにないことだろうけど。
(少なくとも今の自分の負荷だと厳しいかなぁ)
って、言い始めるとキリがないので、ドキュメントでは
対象になってるものの方を列挙した方がいいかな。
(今すでに何が対象外になってるのか言い切れない...)
CB の検索結果、検索条件、ScalarSelect
Bhv の一件登録・更新、バッチ登録・更新、
queryUpdate(), queryDelete()
この辺もろもろ試してみてください。
※こっちは、MySQLのSQL関数のエラーで
ちょっとテストが進んでない...
引き続き、01-SNAPSHOTを出しました。
(まあ、要は最新を常にチェックしてくれればと)
queryInsert()でselect句の暗号化を抑制するの忘れてたので
反映しました。ただ、queryInsert()でもアプリからの固定値の
指定をした場合は、その値だけは暗号化されるようにしました。
要は、アプリから渡す値は暗号化、DB to DB は何もしない、
って感じですね。
DBから取得する値は復号化 but DerivedReferrer は技術的に
今のところ対象外。(どこをどう直すのかを考えるのが大変...)
> CB の検索結果、検索条件、ScalarSelect
> Bhv の一件登録・更新、バッチ登録・更新、
> queryUpdate(), queryDelete()
加えて、関連テーブルとして取得した場合(setupSelect)や、
inline() や on() などを試してみてください。
(色々なパターンがあるね...30ケースはテスト書かないとかな)
2011/5/21 kubo <dbf...@gmail.com>:
> hex(aes_encrypt(%1$s, '%2$s'))
> convert(aes_decrypt(unhex(%1$s), '%2$s') using utf8)
おお、この辺まさしく知りたかったところw
こっちでのテストでも利用させてもらうね。
> ※MySQLだと、引数にイニシャルベクターがないんですよね。
> 内部的にどうしてるんでしょ。javaやoracleにはあるのに。
ふむふむ。
> ※毎回キーをクエリに含めるのは抵抗あるので、
> 事前に変数に含める(SELECT @key:='password';)か、
> キー取得のファンクション、もしくは暗号復号化自体のファンクションを作る必要がありますね。
> (とりあえずサンプルなんで。)
なるほど。いいですね、ありがとう。
こういう話もMLに含まれてると、より実践的な情報となるので。
(DBFluteをきっかけにこういう話の情報共有の場にもなればと)
> 現在の確認状況です。
> CB の検索結果 OK
> CB の検索結果(setupSelect) OK
> CB の検索条件 OK
> ...
ありがとう。引き続きよろしくです。
(こっちはまだ二個しかテスト書けてない...)
※とりあえず簡単なドキュメント書くかなぁ
2011/5/22 awaawa <p1us3i...@gmail.com>:
> dbflute-mysql-exampleで動作確認しようと作業した際に気づいたことです。
> 以下のファイルの「mysql-for-windows.zip」記述は不要かと。
> dbflute-mysql-example/readme.txt
> } else if (mac) {
> download "mysql-for-macosx.zip"
> from "http://dbflute.sandbox.seasar.org/download/misc/mysql-
> community/mysql-for-windows.zip"
> }
> ※あとwindows版は、「mysql-for-windows.zip」ではなく、「mysql-noinstall-5.0.xx-
> win32.zip」なのは理由があるのでしょうか。
ありがとう。直しました。
記述してたURLのページの内容がどんどん変わっていくのね。
そもそも既に Windows 版の zip がどこにもいない!?
ということで、どっちもDBFlute内での再配布のURLを書きました。
(ちなみに、Mac版がダウンロードできるところがどこにも見当たらない...)
> P.S.
> twitter、ブログでも話題になっていたことですが、
> 自分もdbflute-mysql-exampleでライブラリ解決がうまくできません。試行錯誤中。
> (m2eclipse-lightを使っています。)
M2EclipseとQ4Eは解決できるようになってるけど、light だと
また別の classpathentry を追加しないといけないんじゃないかな?
それが何なのかわかるなら追加しておくよ。
(.classpath に一行追加するだけでいいはず!?)
> 引き続き行います。
> 最近業務が立て込んでる都合上、平日は若干レスポンスが遅くなります。すいません。
そもそも業務が立て込んでないって話を
一度も聞いたことがないような...
(二年以上は立て込んでるようなイメージがあるw)
DerivedReferrer も対応しました。
02-SNAPSHOTです。
こっちは基本のテストは置いてけぼりにして、
DerivedReferrer を先にやりました。
2011/5/22 awaawa <p1us3i...@gmail.com>:
> 外部URLだと、どうしてもそうなってしまいますよね。
> example動作をスムーズにすることが優先なので、内部でいいと思います。
>
> 一応、MySQLのダウンロードURLです。(ここならdownloadできるかと。)
> http://www-jp.mysql.com/downloads/mysql/5.0.html
> http://www-jp.mysql.com/downloads/mysql/5.1.html
> http://www-jp.mysql.com/downloads/mysql/5.5.html
ありがとう。
...
...
...Macはやはり選べないねぇ
> org.maven.ide.eclipse_light.MAVEN2_CLASSPATH_CONTAINER
> ただ、なぜか以下の二つのjarが取得できませんでした。
> pomにpluginRepositoryを適当に追加したら取得できました。(根本解決にはなりませんが。)
> mysql:mysql-connector-java:jar:5.1.6:runtime
> org.apache.geronimo.specs:geronimo-j2ee_1.4_spec:jar:1.0:runtime
pluginRepositoryで解決って変な話だねぇ...
>> 02-SNAPSHOTです。
> アップします。
よろしくー
2011/5/23 awaawa <p1us3i...@gmail.com>:
>> ...Macはやはり選べないねぇ
> 5.1と5.5では選べますが、5.0は無理みたいですね。。。
いずれ、Example環境も 5.5 にするかなぁ...
(あと、いま作ってるハンズオンチュートリアルとかでも)
ライセンス的に大丈夫な「はず」というのはあっても、
本当は再配布もあんまりしたくないので。
ただ昔、5.1 を試したときに、起動コマンドとかがちょっと
変わったりしてて、単純には移行できなかった記憶が。
2011/5/23 awaawa <p1us3i...@gmail.com>:
> あまりMySQLいじったことがないので、あれですが。
> 5.1と5.5では、my.cnf(ini)の定義も結構違うみたいです。
>
> ネット情報を参考にして、
> 定義すると5.5だとエラーになることがよくあったので。
> (ネット情報は5.0、5.1がやはり多いです。)
ああ、そこのレベルでもそうなっちゃうかぁ...
ありがとう。よほど手が空いたらアプローチしますw
2011/5/23 awaawa <p1us3i...@gmail.com>:
すっごい簡単ながらドキュメント作りました。
// 暗号化・復号化処理の組み込み | DBFlute
http://dbflute.sandbox.seasar.org/ja/manual/function/genbafit/projectfit/gearedcipher/index.html
書いてある通り、ConditionBean の
ScalarCondition と ColumnQuery は対象外です。
暗号化された状態のまま比較されるので実質利用できない。
頑張ればできなくはないんだけど、対費用効果が低過ぎるのと、
どうしてもファンクションインデックスが必要になるような
SQLになってしまうので、これはきっぱりやらない方がいいのかなと。
2011/5/23 kubo <dbf...@gmail.com>:
> 書いてある通り、ConditionBean の
> ScalarCondition と ColumnQuery は対象外です。
> 暗号化された状態のまま比較されるので実質利用できない。
> 頑張ればできなくはないんだけど、対費用効果が低過ぎるのと、
> どうしてもファンクションインデックスが必要になるような
> SQLになってしまうので、これはきっぱりやらない方がいいのかなと。
といいつつ、気力が出たのでやってみました。
パフォーマンスはさておき、つじつまの合う挙動にはできたかなと。
まあ、実務では使わないでしょう。
厳密なこと考えると、物理的なカラムのデータ型は文字列だけど
論理的なデータ型(Java上での型)は数値、っていう風なマッピングが
できないとだめだね。
> まだ、ガンガン利用できているわけではありませんが、
> 便利に使わせてもらっています。
おお、そうかそうか、ありがとう。
それは安心した。
> # 別件です。
> # dbflute/embedded/templates/om/java/bsentity/dbmeta/DBMetaImpl.vm
> # の253-257行目のgetDaoTypeNameですが、現状も必要でしょうか。
> # 自動生成の結果、「${myExtendedDaoPackageName}」が展開されていませんでした。
> # 自分のdfpropの設定ミスのせいでしょうか。
まあ、厳密には要らないね。
自分もこないだ思い出したかのように気付いた。
0.8.x 以前のモードと共存して存在しているのだけど、
(なので、0.9.0以降だと固定で null)
もう今のバージョンで 0.8.x 用のソースを自動生成する
ことはないので、さくっと消しちゃっても問題はないので、
どこかのタイミングで消すかもしれません。
2011/6/8 awaawa <p1us3i...@gmail.com>: