Home日記コラム書評HintsLinks自己紹介
 

フィンローダのあっぱれご意見番 第158回「パスワードを暗号化するパスワードを…(以下略)」

← 前のをみる | 「フィンローダのあっぱれご意見番」一覧 | 次のをみる →

@nifty のフォーラムを自動的に巡回していろいろ処理するための Mawou というソフトウェアを作っている、 という話を前回書いた。 このプログラム、手元では割と普通に動いている。 仕様策定には大勢の方(脚色アリ)のご意見を参考にさせていただいたが、 コーディングとか、 誰か手伝ってくれないかと思うわけだが、 現時点で未公開だし、まだ一人で作業しているという状況なので、 途中で勝手に仕様を大変更することがある。

  

ユーザーインターフェースの記事で試作したプログラムが、 実はこの Mawou の一部として実装されている。 この種のプログラムで一番大変なのは、 実際に掲示板に書かれているメッセージを取ってくるという処理だ。 特に、ログインしないと get できないようなデータは大変である。 ちなみに、Mawou の初期のデバッグで一番手間取ったのがクッキーの処理だった。 基本的に、テストファーストのつもりでプログラミングしているのだが、 実際にクッキーの処理がうまく行くことは、 複数のフォーラムを巡回するまで確認できなかったのである。

 

※ ログイン手順とか、 どういうときにどんなクッキーが必要になる、 といった情報は公開されていないため、 模倣してテストすることが難しい。

とにかく、発言を get する機能や、ログインする機能は、既に作ってあった。 だから、フォーラムのメッセージを処理する機能は比較的簡単に書けたのだ。 GUIの部分を除いては。

Mawou は、フォーラムを巡回して、新規発言だけを get し、それを手元のパソコンに HTML の形式で保存し、ブラウザで見たり、メールで誰かに知らせる、というような機能を想定していた。 しかし、HTML のデータを作るには、ページデザインが問題になってくる。 見せる情報は、題名、発言者、その人のサイトやメールアドレス、日時、その他いろいろな情報が発言に付随していて、それをどう見せるかだけでも悩ましい。

そこで、方針を変更して、 発言データは XML で生成して、それを HTML に変換する、という二段構えの構造にした。 XML のデータをは、xslt を使って HTML に変換できる。 xslt をユーザーが勝手に差し替えれば、 好みのデザインに変更できる、という仕組みだ。 実際は xalan を使っているのだが、それらの処理を ant を使って行う、 という処理の流れにした。 Mawou は一連の処理の一部として、ant から呼び出すのである。

  

ant も実は初心者なので、 イマイチよく分からなくて使いこなせていない。 例えば、複数のファイルに対して java アプリケーションを起動する方法が分からない。

 

※ foreach で引数を与えるような繰り返し処理をイメージしているのだが、 結局、そのようなタスクはないのでは?

例えば、特定のディレクトリにあるファイルの中から、 内容が更新されているものだけを別ディレクトリにコピーしたいとする。 これは ant を使えば実に簡単に書ける。 List 1 がその一部だ。

---- List 1 ant を使って更新されているファイルだけを上書きする ----

    <copy todir="compare">
     <fileset dir="build/site">
      <different targetdir="compare"
       ignoreFileTimes="true"/>
     </fileset>
    </copy>

---- List 1 end ----
  

サイトのトップだけを修正したのに、 全ファイルを再生成してしまうことがある。 そのときに、ファイルの生成時刻を使って更新されたかどうかを判断すると、 内容は全く同じなのに、生成時刻が新しくなっているので、 全て処理することになってしまう。 そこで、再生成したファイルを、一度別のディレクトリにコピーしておき、 今回の生成分と前回分を実際に比較するというヘンな処理を考えたのだ。

 

※ touch とか使って時刻を戻す方が簡単かもしれない。

ところが、これを「コピーする」のではなくて「java アプリケーションを起動する」ということにすると、途端に難しくなってしまうのだ。 このような処理は、 フォーラム単位で Mawou をそれぞれ起動するために必要になるのだが、 とりあえず、Mawou 側で複数の XML ファイルを指定できるような機能を作っておけば、 目的の動作に近いことはできるので、 あまり真剣に考えずに未解決のまま放置してある。

§

フォーラムを自動巡回するには、一つ大きな問題がある。 フォーラムのサービスを全て使うには、@nifty にログインしなければならない。 つまり、IDとパスワードをサーバーに送信しなければならないのだ。 Mawou に、IDとパスワードをどうやって記憶させるのか? もちろん、アプリケーションをユーザーが手で起動するなら、 そのときにユーザーが指定すればよい。 問題は、LINUX で cron を使って定時に勝手に実行したいような場合である。

  

どこかにパスワードを書いたファイルを保存しておく手はある。 セキュリティ的には推奨できないが、それも一つのやり方だ。 他には、コマンドラインオプションでIDやパスワードを指定できるように設計して、 crontab で実行するスクリプトに書く、というやり方もあるが、 これも、crontab の予約ファイルにIDとパスワードが書かれてしまうので、 本質的には同じことだし、 ps -ef とかで他の人に見られてしまうのは面白くないかもしれない。

 

※ ps -ef は実行中のコマンドを引数込みで表示する。

とりあえず、Mawou はパスワードを暗号化した状態で保存することにした。 ファイルを見られても分からないようにしようというのだ。 一般に、ローカルサーバーで認証するためのパスワードなら、 不可逆な変換で暗号化した状態で保存できる。 変換後のデータをマッチングすれば認証できるし、 変換後の情報を盗まれても、パスワードを知ることは困難だから安心できる。 しかし、今回は、別のところにあるサーバーに実際にパスワードを送信するのだから、 可逆変換にする必要があるのだ。

  

Mawou はオープンソースにする予定である。 つまり、いつかは復号化するコードが公開されてしまう。 もっとも、 Mawou は Java に用意されている標準的な暗号化の処理を使っているだけなので、 特にヘンなことは何もしていない。 何なら今お見せしよう、ということで List 2 である。

 

※ まだソースは公開されていない。

---- List 2 パスワードを復号する処理 ----

    private byte[] decrypt(byte[] text) {
        SecretKeySpec skeySpec = new SecretKeySpec(
            pi.getEncodedKey(), algorithm);

        Cipher cipher = null;
        cipher = Cipher.getInstance(algorithm);
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = null;
        decrypted = cipher.doFinal(text);
        return decrypted;
    }

---- List 2 end ----

Java のこの種の処理をご存知の方ならご覧の通りで、 Java の公式サイトに出ているドキュメントのサンプルと何ら変わらない。 つまり、誰でも知っている類のコードである。 Java を使えば、復号化の処理はこの程度で書けるのだ。 ただ、実際は例外処理がわんさか付いてくるのだが、それは省略してあるので、 真似する場合は注意して欲しい。

まあとにかくかなり割り切るしかないという結論にして、 Mawou はID、暗号化したパスワード、 暗号化キーの3つの情報をファイルに保存することにした。 別にファイルでなくても DB に入れても構わないのだが、とにかくこの3つは保存する。 しかし、このファイルが盗まれたら困るのではないか。 実際、パソコンを勝手に使われるとか、盗まれる、というような事件が結構起きているのではないか。

ということで、もう一つ壁を作ることにした。 パスワードをそのまま暗号化するのではなく、 事前にユーザーが指定したキーを使って変換してから暗号化するのだ。 要するに二重に暗号化を行うのである。 このときのキーを「Mキー」と呼ぶことにしよう。 Mキーは、Mawou を起動するときに指定する。 つまり、ファイルには保存しない。 ファイルに保存されている、IDと暗号化されたパスワードと暗号化キーは ファイルをコピーされたら簡単に盗まれてしまうが、 Mキーは、どこにも保存されていない。 これが壁になる。

  

例えば、IDがSDI00344、パスワードが hogehoge、Mキーを hello とする。 Mawou は、SDI00344 という情報と、 hogehoge を hello によって変換した何か別のバイト列をファイルに保存するのだ。 このバイト列を、仮に mokyuuuu としよう。 mokyuuuu はさらに暗号化されるから、 ファイルに書かれる情報は、SDI00344 と、mokyuuuu を暗号化した謎のバイト列、暗号化キー、この3つとなる。

 

※ mokyuuuu という文字列にはあまり意味がないが、 全く意味がないわけでもない。

仮にこれら全部を盗まれて、ファイルを直接見られても mokyuuuu という文字列すら分からない。暗号化されているからだ。 ただ、これはプログラムを作れば解読できてしまう。 その結果分かるのは、SDI00344と、mokyuuuu という情報である。 hogehoge ではない。 だから、これだけではまだ @nifty にログインすることはできない。

逆に、誰かに Mawou を使っているところを見られて、Mawouキーがバレてしまったとしよう。バレるのは hello というMキーだけである。 パスワードそのものは分からないから、 この情報だけでは @nifty に勝手にログインすることはできない。 ただ、その人は、この端末から Mawou を起動することができるようになる。

ということで少し安全っぽくなった。 ただ、実際に cron で Mawou を実行するのであれば、例えば crontab に、

/usr/local/bin/mawou -key=hello

のように指定すると、ps -ef などでMキーがバレてしまう。 見られては困るという場合は、これらをスクリプトファイルに書いておき、 crontab はスクリプトを呼び出す、という二段構えにすればいいが、 結局それもファイルに書いたら盗まれたときにバレてしまう。 だったら、Mキーも暗号化すれば?

とか考えているといつまでたっても終わらない。 もっと本気で安全化するのなら、 IDとパスワードを覚えている専用サーバーをローカルマシンで起動しておき、 Mawou はそれと通信してパスワードを受け取る、 というような処理まで考えたのだが、 たかがpcの巡回ソフトにそこまで…という気もしたので、 まあこのあたりが落とし所ではないかと思って、妥協点にしたのだが、 さて、 ちなみに、そこまでやっているのだろうか、他の巡回ツールは?

  

(C MAGAZINE 2005年8月号掲載)
内容は雑誌に掲載されたものと異なることがあります。

修正情報:
2006-03-01 裏ページに転載。

(C) Phinloda 2005-2006 All rights reserved.