【PHP8.x】random_bytes関数の使い方

random_bytes関数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

『random_bytes関数は、暗号学的に安全なランダムなバイト列を生成する関数です』この関数は、オペレーティングシステムが提供する信頼性の高い乱数ソースを利用して、予測することが極めて困難な質の高い乱数を生成します。そのため、セッションID、パスワードリセット用のトークン、APIキー、暗号化キーといった、セキュリティが重要となる場面で推測不可能な値を生成するのに最適です。従来のrand()mt_rand()といった関数も乱数を生成しますが、これらは統計的な目的で設計されており予測可能であるため、セキュリティ関連の用途には絶対に使用してはいけません。random_bytes関数は、引数に生成したいバイトの長さを整数で指定すると、その長さのランダムなバイト列を文字列として返します。返される値はバイナリデータであり、必ずしも人間が読める文字で構成されているとは限りません。引数に0以下の整数を指定するなど、不正な値が渡された場合にはValueError例外が発生します。この関数は、現代のPHPアプリケーションにおいて、安全なランダムデータを生成するための標準的な方法です。

構文(syntax)

1$bytes = random_bytes(int $length);

引数(parameters)

int $length

  • int $length: 生成するランダムなバイト列の長さをバイト単位で指定する整数

戻り値(return)

string

指定されたバイト数分の、暗号学的に安全なランダムなバイト列を文字列として返します。

サンプルコード

PHP random_bytes 代替関数で乱数生成する

1<?php
2
3/**
4 * OpenSSL拡張モジュールが利用できない環境で、`random_bytes`関数の代替として、
5 * `random_bytes`と同じように暗号論的に安全な擬似乱数バイト列を生成します。
6 *
7 * @param int $length 生成するバイト数
8 * @return string 生成されたランダムなバイト列、エラーが発生した場合はnull
9 */
10function random_bytes_alternative(int $length): ?string
11{
12    $result = '';
13    try {
14        // `/dev/urandom` が利用可能であればそれを使用
15        if (is_readable('/dev/urandom')) {
16            $fp = fopen('/dev/urandom', 'rb');
17            if ($fp) {
18                $result = fread($fp, $length);
19                fclose($fp);
20            }
21        }
22
23        // `/dev/urandom` が利用できない場合は `openssl_random_pseudo_bytes` を使用
24        if (empty($result)) {
25            $result = openssl_random_pseudo_bytes($length, $strong);
26            if (!$strong) {
27                // openssl_random_pseudo_bytes が暗号学的に安全な乱数を生成できなかった場合
28                throw new Exception("openssl_random_pseudo_bytes did not generate cryptographically strong random bytes.");
29            }
30        }
31
32        if (strlen($result) !== $length) {
33             throw new Exception("Could not gather sufficient entropy for requested number of bytes.");
34        }
35
36        return $result;
37
38    } catch (Exception $e) {
39        error_log("random_bytes_alternative failed: " . $e->getMessage());
40        return null;
41    }
42}
43
44// 使用例
45$randomBytes = random_bytes_alternative(16);
46
47if ($randomBytes !== null) {
48    echo bin2hex($randomBytes) . PHP_EOL; // 16進数で表示
49} else {
50    echo "Failed to generate random bytes." . PHP_EOL;
51}
52

このサンプルコードは、PHPの組み込み関数 random_bytes が利用できない環境における代替手段として、暗号学的に安全な擬似乱数バイト列を生成する random_bytes_alternative 関数を定義しています。

random_bytes 関数は、指定されたバイト数のランダムな文字列を生成しますが、このサンプルコードでは、まず /dev/urandom という特殊なファイルからの読み込みを試みます。これは、Linux系システムで利用できる乱数生成器です。もし /dev/urandom が利用できない場合は、openssl_random_pseudo_bytes 関数を使用して乱数を生成します。

openssl_random_pseudo_bytes 関数は、OpenSSL拡張モジュールの一部であり、擬似乱数を生成します。この関数は、第2引数 $strong に真偽値を設定し、生成された乱数が暗号学的に安全かどうかを判断できます。安全でないと判断された場合は、例外をスローします。

random_bytes_alternative 関数は、引数 $length で生成するバイト数を指定します。戻り値は、生成されたランダムなバイト列を含む文字列です。エラーが発生した場合は null を返します。生成されたバイト列の長さが指定された $length と異なる場合も例外をスローします。

このサンプルコードの利用例では、16バイトのランダムなバイト列を生成し、bin2hex 関数を使って16進数形式で表示しています。乱数の生成に失敗した場合は、エラーメッセージを表示します。random_bytes 関数が利用できない環境でも、同等の安全性を目指した乱数生成処理を実装する際の参考になります。

random_bytes_alternative関数は、random_bytes関数の代替として、暗号学的に安全な乱数を生成することを目的としています。/dev/urandomまたはopenssl_random_pseudo_bytesを利用しますが、環境によっては期待通りの動作をしない可能性があります。openssl_random_pseudo_bytesで生成された乱数が、暗号学的に安全かどうかを$strong変数で確認することが重要です。生成に失敗した場合(nullが返された場合)のエラー処理を必ず実装してください。生成されたバイト数が要求された長さと一致するか確認し、不一致の場合は例外をスローすることで、不完全な乱数によるセキュリティリスクを回避できます。

PHP random_bytesで安全なバイト列を生成する

1<?php
2
3/**
4 * 指定された長さの暗号学的に安全なランダムなバイト列を生成するサンプル
5 *
6 * @param int $length 生成するバイト列の長さ
7 * @return string 生成されたランダムなバイト列
8 */
9function generateRandomBytes(int $length): string
10{
11    try {
12        $bytes = random_bytes($length);
13        return $bytes;
14    } catch (Exception $e) {
15        // 例外処理:ランダムなバイト列の生成に失敗した場合
16        error_log("ランダムなバイト列の生成に失敗しました: " . $e->getMessage());
17        return ''; // または、エラー処理に応じた値を返す
18    }
19}
20
21// 使用例:16バイトのランダムなバイト列を生成する
22$randomBytes = generateRandomBytes(16);
23
24if ($randomBytes !== '') {
25    echo "生成されたランダムなバイト列 (16進数): " . bin2hex($randomBytes) . PHP_EOL;
26} else {
27    echo "ランダムなバイト列の生成に失敗しました。" . PHP_EOL;
28}

PHPのrandom_bytes関数は、指定された長さの暗号学的に安全なランダムなバイト列を生成するために使用されます。この関数は、パスワードの生成、セッションIDの作成、暗号化キーの生成など、セキュリティが重要な場面で利用されます。

引数$lengthは整数型で、生成するランダムなバイト列の長さをバイト単位で指定します。例えば、$lengthに16を指定すると、16バイトのランダムなバイト列が生成されます。

戻り値は文字列型で、生成されたランダムなバイト列が返されます。もしランダムなバイト列の生成に失敗した場合(例えば、システムが十分なエントロピーを持っていない場合)、例外がスローされる可能性があります。サンプルコードでは、この例外をtry-catchブロックで捕捉し、エラーログにメッセージを記録するようにしています。

サンプルコードでは、generateRandomBytesという関数を定義し、random_bytes関数を呼び出してランダムなバイト列を生成しています。生成されたバイト列は、bin2hex関数を使って16進数の文字列に変換され、画面に表示されます。bin2hex関数は、バイナリデータを16進数の文字列に変換する便利な関数です。生成に失敗した場合は、エラーメッセージが表示されます。このように、random_bytes関数と例外処理を組み合わせることで、安全で信頼性の高いランダムなバイト列を生成することができます。

random_bytes関数は、暗号学的に安全な乱数を生成する関数です。引数$lengthで生成するバイト数を指定します。生成に失敗した場合、例外が投げられる可能性があるため、try-catchブロックで囲み例外処理を行うのが安全です。生成されたバイト列はバイナリデータなので、bin2hex関数などで16進数に変換して表示すると扱いやすくなります。エラー処理では、詳細なエラー内容をログに出力すると、問題発生時の原因特定に役立ちます。生成された乱数は、パスワードの生成や暗号化キーの生成など、セキュリティが重要な場面で利用できます。

関連コンテンツ