はじめに
「セッションIDの文字列長を32文字以上にしろ」と言われて調査したことを書きます。
Linux 上で動く PHP 5.x での話です。
セッションIDに関係する4つの設定
セッションIDの生成方法を設定するには、以下の4つのパラメータをいじります。
session.entropy_file
session.entropy_length
session.hash_function
session.hash_bits_per_character
ここで重要なのは、文字列長を直接指定するパラメータは無いということです。
Q:じゃあどうすればいいの?
A:すっ飛ばさずにちゃんと読んでください。
session.entropy_file
/dev/urandom を指定します。
セッションIDは、セッションハイジャックなどを防ぐために「デタラメな文字列」である必要があります。それを作る元となるデタラメなデータを作ってくれるファイルがコレです。
「デタラメなデータ」って、簡単なようですんごい難しくて、ハッカーから見て予測不可能なデタラメさが必要となります。/dev/urandomから、暗号の偉い人たちが考える最強のデタラメなデータが流れてくると思ってください。
session.entropy_length
先の、session.entropy_length で指定したファイルから何バイト読み込んでくるかを指定します。
小さいと「デタラメ度」が小さくなってしまいます。
大きいと、計算時間が無駄になってしまいます。
また、ここの数値はセッションIDの長さとはなんら関係ありません!
最適な値はいくつになるのか? というのは、次の session.hash_function で指定するハッシュアルゴリズムにより異なります。
session.hash_function
ハッシュ関数を指定します。ハッシュ関数の意味が分からない方はwikipediaでも読んでください。(最初の概要部分だけでもいいかな)
session.entropy_fileで指定したファイルからsession.entropy_lengthで指定したバイト数分読んできて、それをsession.hash_functionで指定したハッシュ関数にかけます。
session.hash_functionは
0を指定すると MD5 になります。
1を指定すると SHA-1 になります。
PHP 5.3.0 以降では、文字列で任意のハッシュ関数を指定することができます。
使用できるハッシュ関数は hash_algos() で知ることができます。
コマンドラインからは php -r 'print_r(hash_algos());'
で調べることができます。
で、何がお勧めかというと、sha1 でしょうか。
sha1 の場合、ブロック長は512bits(64バイト)なので、session.entropy_length には 64 を指定するのが良いと思います。
session.hash_bits_per_character
先のハッシュ関数からの出力はバイト列なので、文字列に変換する必要があります。その際、何ビット毎に1文字にするのかを指定するのがこのsession.hash_bits_per_characterというパラメータです。
4,5,6 のどれかを指定できます。
session.hash_function に sha1 を指定していた場合、SHA-1の出力は160bit ですので、セッションIDの長さは 160÷session.hash_bits_per_character になります。
小数は切り上げです。
表にまとめると以下のようになります。
hash_bits_per_character | セッションIDの文字列長 |
---|---|
4 | 40 |
5 | 32 |
6 | 27 |
ここで注意したいのは、session.hash_bits_per_characterを変えたことによって文字列長が長くなったからと言ってセキュリティ強度が上がったわけではないという点です。
4にすると文字種が減るので、組み合わせの数としては変わりません。
様々な組み合わせでの設定
考えられる設定はたくさんあります。
しかし、
- 今更 MD5 はないだろう
- 256bitもあれば十分だろう
- hash_bits_per_character に 4 を採用する理由はないだろう
といったことを考えると、以下の組み合わせあたりが合理的な設定かなと思います。
entropy_length | hash_function | hash_bits_per_character | セッションIDの文字列長 |
---|---|---|---|
64 | sha1(1) | 5 | 32 |
64 | sha1(1) | 6 | 27 |
64 | sha224 | 5 | 45 |
64 | sha224 | 6 | 38 |
64 | sha256 | 5 | 52 |
64 | sha256 | 6 | 43 |
hash_bits_per_character に 5 を設定するケースは殆どないと思いますが、セッションを保存するストレージに大文字小文字を判別しないファイルシステムを使う場合(簡単に言うとwindowsの場合)は 5 を使うほうがよいです。