SMART LLC

暗号論的擬似乱数生成器(CSPRNG)

公開日:2014/10/25

暗号論的擬似乱数生成器(CSPRNG)なるものの存在を知ったのでメモする。
CSPRNGはCryptographically Secure Pseudo Random Number Generatorの略。

暗号論的擬似乱数

まず世の中には大きく分けて2種類の乱数がある。
一つはサイコロみたく次の目がどうやっても予測できない、計算を必要としない(計算できない)真の乱数。
もう一つは決まった計算によって生成される擬似乱数。
ソフトウェアで登場する乱数は当たり前だけど擬似乱数。
ソフトウェアは決められたとおりにしか動作しないから真の乱数を生成することはできない。
そこで時間だったり外部からの入力情報を元に決められた計算をして擬似的な乱数を生成している。
その擬似乱数の中にもさらに暗号論的擬似乱数なるものがあることを最近知った。
wikipedia曰く「Σ = {0,1}とする。自然数 k に対し、Σk 上の一様分布を Uk と表す。確率変数の族 {Xk}k∈N が、一様分布の族 {Uk}k∈N と計算量的識別不能な時、族 {Xk}k∈N は暗号論的擬似乱数であるという。」ということらしい。
うーんわからん( ゚д゚)
「l(k) を l(k) > k を満たす多項式とする。G を多項式時間アルゴリズムで、G に k ビットのビット列を入力をすると l(k) ビットの出力を返すものとする。すると G(Uk) は Σl(k) 上の確率分布である。確率分布の族 {G(Uk)}k∈N が暗号論的擬似乱数である時、多項式時間アルゴリズム G を暗号論的擬似乱数生成機という。」とも。
うーんわからん( ゚д゚)
暗号論的擬似乱数を生成するすげえやつのことを暗号論的擬似乱数生成器と呼ぶことしかわからん_(:3 」∠)_
要は普通の擬似乱数は予測ができるのに対し、暗号論的擬似乱数は予測ができない。
ランダムテストには普通の擬似乱数でいいけどパスワードとかトークンとかバレたら困るものには暗号論的擬似乱数を使えということだ。

PHPの場合

PHPの関数はどうなってるのか。
rand()関数
mt_rand()関数
openssl_random_pseudo_bytes()関数
rand()関数とmt_ramd()関数のページに「この関数が生成する値は、暗号学的に安全ではありません。そのため、これを暗号として使ってはいけません。暗号学的に安全な値が必要な場合は、openssl_random_pseudo_bytes() を使いましょう。」て書いてある。
ということでPHPの暗号論的擬似乱数生成器はopenssl_random_pseudo_bytes()関数(σ・∀・)σ
crypt()関数を使ってパスワードをハッシュする方法でsaltつくるのにmt_rand()関数使ってたので書き換えてみる。
他にも/dev/randomとか/dev/urandomを使う方法もあるけどサーバOSを問わないopenssl_random_pseudo_bytes()関数を採用。

saltをmt_rand()関数で生成してた。

$salt = '$2a$10$';
for ($i = 0; $i < 22; $i++) { 
    $salt = $salt.substr('./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', mt_rand(0, 63), 1); 
}
$salt = $salt.'$';
echo $salt;

openssl_random_pseudo_bytes()関数に書き換えた。

$salt = '$2a$10$';
$salt = $salt.bin2hex(openssl_random_pseudo_bytes(11));
$salt = $salt.'$';
echo $salt;

こうなった。

$2a$10$4424d85a7552381596f581$

openssl_random_pseudo_bytes()関数の戻り値はバイト文字列だからそのままじゃ使えない。
bin2hex()関数で16進数に変換してやる。
openssl_random_pseudo_bytes()関数のパラメータはバイト長なので16進数22桁に変換するから11。
なぜ半分か。
1バイトてのは8ビット。
8ビットてのは2の8乗。
2の8乗てのは16×16。
つまり1バイトを16進数で表すと2桁になる。
ASCIIコード(1バイト文字)を16進数2桁で書くアレ。
16進数が気になるならbin2hex()関数の代わりにbase64_encode()関数を使う手もある。

今はクロスサイトスクリプティング(XSS)攻撃とクロスサイトリクエストフォージェリ(CSRF)攻撃によるセッションハイジャック(なりすまし)について調べてる。
webセキュリティてほんと今まで全然気にしてこなかったけど大変。
こりゃいろんなところでいろんなニュースになるわ。
何もわかってないでwebシステムつくったりホームページつくってる奴らもたくさんいるんだろなきっと。
気を付けよ。

SHARE