- PR -

JDBC経由のパスワードの暗号化とデータ登録方法について

1
投稿者投稿内容
faulter
会議室デビュー日: 2005/03/06
投稿数: 11
投稿日時: 2005-03-18 14:59
お世話になっております、皆々様。

現在以下の開発環境で開発しています。
言語:Java(JSP、Servlet)
環境ツール:eclipse3.0
コンテナ:Tomcat5.5.7

今回、JDBCレルムによって、ログインの認証と
パスワードの変更を行います。
その際、パスワードは暗号化されており、
レルムの設定でその形式(MD5など)を指定します。

それでログインの認証には成功しているのですが、
問題はパスワードの変更です。

レルムの機能を使用して、パスワードを暗号化、
データの登録を行いたいと言う要望なのですが、
(server.xmlを書き換えれば、暗号化方式の変更にプログラムの変更を伴わずにすむ為)
この方法が良く分かりません。

org.apache.catalina.realm.User クラスを使用するとできそうですが、
これを単純にeclipse上でjavaファイルにimportステートメントでインポートしても、
エラーになり、CATALINA_HOMEをBuilderPathに設定しようとしても、
"Variable in the archive path does not exist"
で、追加できません。
上記のパスワードの変更方法と、eclipseで認識されないクラスの設定方法を
ご存知の方がいらっしゃいましたら、教えてください。
よろしくお願いします。
aa
ぬし
会議室デビュー日: 2004/01/08
投稿数: 299
投稿日時: 2005-03-19 09:11
引用:

レルムの機能を使用して、パスワードを暗号化、
データの登録を行いたいと言う要望なのですが、
(server.xmlを書き換えれば、暗号化方式の変更にプログラムの変更を伴わずにすむ為)
この方法が良く分かりません。


えっと、ちょっと質問された内容とは違うのですけど、
server.xmlでベーシックとかダイジェストとか指定できますけど、それはパスワード入力の時の話ですよね。パスワード変更させるときに、その新しいパスワードがネットワーク上に平文で流れたのではそもそも意味がないと思います。
(そこでクライアント側で暗号化を実装してというお考えだとは思いますが。)

Webアプリの場合、サーバ側のアプリの変更を伴わないように、SSLとかIPsecを使うとかする方がシンプルでよいと思います。
はしもと
大ベテラン
会議室デビュー日: 2003/02/05
投稿数: 182
投稿日時: 2005-03-21 10:09
以下と関連しているでしょうか。
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=11850&forum=12

それと org.apache.catalina.realm.User クラスって有りましたっけ ?
faulter
会議室デビュー日: 2005/03/06
投稿数: 11
投稿日時: 2005-03-22 15:11
aa、はしもと様
返答ありがとうございます。

aa様の言う通り、
パスワード変更の際、パスワードが平文で
登録されては意味がないので、
パスワードを暗号化して流します。

今回のプロジェクトでは、SSLなどは使用せず、
あくまでTomcatのレルム機能を用いて
暗号化と認証を行いたいのだそうです。
(理由は顧客がどのような暗号化を希望あるいは
変更を要望しても対応しやすいように。)

その暗号化でTomcatのRealmで
Digestを適当なで選択すれば、
あとはTomcatがそれで暗号化して(MessageDigestメソッド)、
認証が正しければ、ログインすることは分かっています。

で、
org.apache.catalina.realm.User クラス
はすみません、これはインターフェイスでした。
org.apache.catalina.realm.UserDatabaseRealm
はクラスで、これをインスタンス化して
getDigestメソッドで、暗号化方式を呼び出し、
(getpasswordメソッドがProtectedなので)
それをMessageDigestメソッドで処理すれば
良いのか?!
と考え、やってみたら
初期化ができませんでした。(Newで失敗)
Tomcatでレルム認証の際に生成された
オブジェクトをこのクラスに組み込めれば、
いけるのかと思ったのですが、
この方法が現在分からないので、再び思案中です。。。
Globalnaming Resourceへ追加するといけるかも
と思いながら、入れ方が良く分からない。。。。
Realmに引数(!?)Nameがないので。。

すみません、ぜんぜん解決した報告ではないですが、
とりあえず、現状報告です。
何かいい知恵がありましたら、教えてください。お願いします。

ちなみに、現在、MD5で認証、変更する際、
16進数で戻るので、0埋め処理をしたら、うまくいったのですが、
これは自分の考え方が何かおかしいですか?
下にそのサンプルコードを記述して置きます。
と言うのは、もしこれが必要だと
他の暗号化に変更する際にも、Tomcatがサポートしている暗号化毎に
何か記述しなきゃいけない可能性が出てきてしまうので。。
自分のただの勘違いで"MD5"の記述だけでうまくいくのが望ましいです。

よろしくお願いします。

**********************************************
private String encryptionPassword(String password, String digest)
throws NoSuchAlgorithmException {
String a = null;               //今回は例えば"MD5"
MessageDigest md = MessageDigest.getInstance(digest);
byte[] enc = md.digest(password.getBytes());

return byteArraytoHexString(enc); //下のメソッドに飛ぶ
 }

  ******************************************************
private static String byteArraytoHexString(byte[] md5) {
StringBuffer md5String = new StringBuffer();

for (int i = 0; i < md5.length; i++) {
//byteを一つ取り、絶対値に変換する
int n = md5[i] & 0xff;

//3)16以下の数の場合は頭に0をつける必要がある
if (n < 16){
md5String.append("0");
}

//一つのbyteを16進数に変換
md5String.append(Integer.toHexString(n).toUpperCase());
}

return md5String.toString();
}
************************************
はしもと
大ベテラン
会議室デビュー日: 2003/02/05
投稿数: 182
投稿日時: 2005-03-22 18:15
引用:
faulterさんの書き込み (2005-03-22 15:11) より:
org.apache.catalina.realm.UserDatabaseRealm
はクラスで、これをインスタンス化して



org.apache.catalina.realm.RealmBase の派生クラスが
ユーザデータベースを変更する事はありません。
この事はウェブのドキュメントに書いてあります。

そもそも、ユーザデータベースの管理はレルムの機能では無く、
org.apache.catalina.UserDatabase インターフェースの機能です。
UserDatabaseRealm を使うとユーザデータベースが更新される様に
見えるのは org.apache.catalina.UserDatabase の実装を
参照しているからです。

その実装として、標準で利用する様に設定されているクラスが
org.apache.catalina.users.MemoryUserDatabase で、このクラスは
ユーザデータベースを XML ファイルに永続化します。

なので、UserDatabaseRealm を使ってユーザデータベースを RDBMS に
永続化したいなら、MemoryUserDatabase に代わってその様な処理を
するクラスを作成する必要があります (誰かが作ってない限り) 。

しかしそれよりも、Tomcat が参照している RDBMS のパスワード
カラムを、直接 UPDATE してしまうアプリケーションを作成する方が
簡単に思える事でしょう。

引用:
他の暗号化に変更する際にも、Tomcatがサポートしている暗号化毎に
何か記述しなきゃいけない可能性が出てきてしまうので。。



Realm 要素の digest 属性に MD5 と指定した場合に参照する
パスワードは標準的な MD5 値です。
Tomcat 用に特別な処理は必要ありません。


[ メッセージ編集済み 編集者: はしもと 編集日時 2005-03-22 18:22 ]
faulter
会議室デビュー日: 2005/03/06
投稿数: 11
投稿日時: 2005-03-27 00:06
はしもと 様

いろいろご指摘ありがとうございました。
ウエブ上のドキュメントも読んでいるのですが、
JDBCレルムをJavaソース上でうまく実装する方法が分からず、
(初期の認証時に使用したはずのJDBCレルムのオブジェクトの
取得方法が分からない)
その周辺(!?)のクラスでいろいろ調べてみてみた、というわけでした。
ただ、その仕様自体はドキュメントを読んだだけではピンと
来なかったのでいろいろ試したのですが、はしもと様の説明で
少しその辺の関連が分かったような気がします、ありがとうございます。

引用:
--------------------------------------------------------------------------------

はしもとさんの書き込み (2005-03-22 18:15) より:
しかしそれよりも、Tomcat が参照している RDBMS のパスワード
カラムを、直接 UPDATE してしまうアプリケーションを作成する方が
簡単に思える事でしょう。
--------------------------------------------------------------------------------

結局、現在有効な方法は見出せていませんが、
上記の方法は、一応できそう(すみません、まだ完全に検証してません。。。)
なので、考えてみたいと思っています。
もう少し、検証してみて、より良い方法を見つけようと考えてます。

diegstの設定方法は、やはり、私の記述の仕方が良くないようでした。
以下の記述で、特に0埋め処理を意識しないですみました。
ありがとうございました。
**********************************************
byte[] digest = MessageDigest.getInstance("MD5").digest(args[0].getBytes());

StringBuffer s = new StringBuffer();

for (int i = 0; i < digest.length; i++) {
      /*Convert "Byte" to "String" with radix 16*/
s.append(Integer.toString((digest[i] & 0xf0) >> 4, 16));
s.append(Integer.toString((digest[i] & 0x0f), 16));
}

**********************************************
1

スキルアップ/キャリアアップ(JOB@IT)