2015年2月4日水曜日

Javaアプリケーションをログオフ中も実行させ続けるには

 Javaアプリケーションを、Windowsのサービスのように利用する(バックグラウンドでずっと実行させ続ける)ためには、通常のWindowsアプリケーションとは違った配慮が必要である。一般的には、Windowsのタスクとして登録しておけば、ユーザーのログオン/ログオフとは関係なく、プログラムを実行させ続けることができるはずである。だがJavaの実行環境の仕様により、たとえタスクとして登録されたプログラムであっても、ユーザーがログオフすると実行中のJavaアプリケーションのタスクが終了してしまう。これはJavaの実行環境が、ログオフに起因するシグナルをキャッチしてシャットダウンしてしまうからだ。

 Javaアプリケーションをログオン/ログオフとは無関係に、ずっと実行し続けたければ、このようなシグナルを無視するオプションを指定するとよい。Java実行環境1.3以降には「-Xrs」というオプションがあり、このオプションを付けて実行すると、ログオフ時のWindows OSによるシグナルを無視して実行を続けることができる。


操作方法
 例えば、次のようなJavaプログラムを作成したとしよう。

※ファイル:Count.java

public class Count {
public static void main(String[] args) throws Exception{
for (int i=0; ; i++){
Thread.sleep(1000);
java.io.FileWriter fw = new java.io.FileWriter("count.txt");
fw.write(Integer.toString(i));
fw.close();
}
}
}
 これは、起動からの経過時間をファイルに出力するプログラムである。実行中は1秒ごとにカレント・ディレクトリの「count.txt」が更新される。このファイルが更新されるかどうかを確認することで、プログラムが実行中かどうかを簡単にチェックできる。

 これをコンパイルし、「java Count」として実行すると、「count.txt」が作成され、1秒ごとに経過時間が書き込まれる。コマンド・プロンプトで「Ctrl+C」を押すか、ログオフするとプログラムは終了する。

 では、これをログオフ中も実行させるために、タスクとして登録してみよう。こうすると、ログオン/ログオフとは関係なく、実行されるようになる。

 まず、コントロール・パネルの[タスク]アイテムを開き、右クリックして表示されるポップアップ・メニュー、もしくは[ファイル]メニューの[新規]−[タスク]を選択する(コントロール・パネルをカテゴリ表示にしている場合には、[パフォーマンスとメンテナンス]の[タスク]アイテムを開く)。作成された新しいタスクに名前を付け、プロパティを開く。[実行するファイル名]は「javaw -Xrs Count」というふうに、-Xrsオプションを付けておく。その下の「開始」テキストボックスにはJavaプログラムを作成したフォルダ名を入力する。

 次に[スケジュール]タブをクリックし、タスクのスケジュールを「システム起動時」とする。

 以上の設定でタスクを登録し、コンピュータを再起動すると自動的にJavaが起動され、ユーザーがログオン/ログオフしても実行が続けられる(-Xrsオプションがないと、ユーザーがログオフすると、プルグラムが終了してしまう)。終了するには[タスクの終了]を実行すればよい。

 なお、「-X」で始まるオプションは非標準であり、バージョンアップに伴って変更される可能性がある。利用の際には、あらかじめ「java -X」などでXオプションが利用できることを確認していただきたい。

2015年1月29日木曜日

PostgreSQLパスワードハッシュ化関数

crypt()およびgen_salt()関数は特にパスワードのハッシュ化のために設計されたものです。 crypt()がハッシュ処理を行い、gen_salt()はハッシュ処理用のアルゴリズム上のパラメータを準備します。

crypt()アルゴリズムは、以下の点でMD5SHA1のような通常のハッシュ処理アルゴリズムと異なります。

1.    低速です。 データ量が少ないためパスワード総当たり攻撃に対して頑健にする唯一の方法です。

2.    結果にはソルトというランダムな値が含まれます。 このため同じパスワードのユーザでも異なった暗号化パスワードを持ちます。 これはアルゴリズムの逆処理に対する追加の防御です。

3.    結果内にアルゴリズムの種類が含まれます。 このため異なるアルゴリズムでハッシュ化したパスワードが混在可能です。

4.    一部は適合型です。 つまり、コンピュータが高速になったとしても、既存のパスワードとの互換性を損なうことなくアルゴリズムを低速に調整することができます。

F-18. crypt()がサポートするアルゴリズム

アルゴリズム

パスワード最大長

適合型かどうか

ソルトビット長

説明

bf

72

はい

128

Blowfishベース、2a

md5

無制限

いいえ

48

MD5ベースの暗号

xdes

8

はい

24

拡張DES

des

8

いいえ

12

元来のUNIX crypt

F.23.2.1. crypt()

    crypt(password text, salt text) returns text
   

passwordcrypt(3)形式のハッシュを計算します。 新しいパスワードを保管する時には、gen_salt()を使用して新しいsaltを生成する必要があります。 パスワードを検査する時、既存のハッシュ値をsaltとして渡し、結果が格納された値と一致するかどうかを確認します。

新しいパスワードの設定例を以下に示します。

    UPDATE ... SET pswhash = crypt('new password', gen_salt('md5'));
   

認証の例です。

    SELECT pswhash = crypt('entered password', pswhash) FROM ... ;
   

入力パスワードが正しければtrueを返します。

F.23.2.2. gen_salt()

    gen_salt(type text [, iter_count integer ]) returns text
   

crypt()で使用するランダムなソルト文字列を新規に生成します。 また、このソルト文字列はcrypt()にどのアルゴリズムを使用するかを通知します。

typeパラメータはハッシュ化アルゴリズムを指定します。 受付可能な種類は、desxdesmd5bfです。

繰り返し回数を持つアルゴリズムでは、ユーザはiter_countパラメータを使用して繰り返し回数を指定できます。 指定する回数を高くすれば、パスワードのハッシュ化にかかる時間が長くなり、それを破るための時間も長くなります。 しかし、あまりに多くの回数を指定すると、ハッシュ計算にかかる時間は数年に渡ってしまう可能性があります。 これは実用的ではありません。 iter_countパラメータを省略した場合、デフォルトの繰り返し回数が使用されます。 iter_countで受け付けられる値はアルゴリズムに依存し、表F-19に示す通りです。

F-19. crypt()用の繰り返し回数

アルゴリズム

デフォルト

最小

最大

xdes

725

1

16777215

bf

6

4

31

xdesの場合、回数が奇数でなければならないという追加の制限があります。

適切な繰り返し回数を選択するために、元々のDES暗号は当時のハードウェアで1秒あたり4個のハッシュを持つことができるように設計されたことを考えてください。 14ハッシュより遅いと、おそらく使い勝手が悪いでしょう。 1100ハッシュより速いというのは、十中八九、あまりにも速すぎるでしょう。

ハッシュ化アルゴリズム別に相対的な速度に関する概要を表F-20にまとめました。 この表は、8文字のパスワード内のすべての文字の組合せを取るためにかかる時間を示します。 また、すべて小文字の英字のみのパスワードである場合と大文字小文字が混在した英字と数字のパスワードの場合を仮定します。 crypt-bfの項では、スラッシュの後の数値はgen_saltiter_countです。

F-20. ハッシュアルゴリズムの速度

アルゴリズム

1秒当たりのハッシュ数

[a-z]の場合

[A-Za-z0-9]の場合

crypt-bf/8

28

246

251322

crypt-bf/7

57

121

123457

crypt-bf/6

112

62

62831

crypt-bf/5

211

33

33351

crypt-md5

2681

2.6

2625

crypt-des

362837

7

19

sha1

590223

4

12

md5

2345086

1

3

注意:

·         Pentium 4 1.5GHzのマシンを使用しました。

·         crypt-desおよびcrypt-md5アルゴリズムの数値はJohn the Ripper v1.6.38-test出力から得たものです。

·         md5の数値はmdcrack 1.2のものです。

·         sha1の数値はlcrack-20031130-betaのものです。

·         crypt-bfの数は、1000個の8文字パスワードをループする単純なプログラムを使用して得たものです。 こうして、異なる回数の速度を示すことができました。 参考までに、john -testcrypt-bf/5213 loops/secでした。 (結果の差異が非常に小さいことは、pgcryptoにおけるcrypt-bf実装がJohn the Ripper(訳注:パスワード解析ツール)で使用されるものと同じであるという事実と一致します。)

"すべての組み合わせを試行する"ことは現実的行使ではありません。 通常パスワード推定は、普通の単語とその変形の両方を含む辞書を使用して行われます。 ですので、いささかなりとも言葉に似たパスワードは上で示した数値よりも速く推定されます。 また6文字の単語に似ていないパスワードは推定を免れるかもしれませんし、免れないかもしれません