Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】X509_PURPOSE_SSL_SERVER定数の使い方

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

作成日: 更新日:

基本的な使い方

X509_PURPOSE_SSL_SERVER定数は、X.509証明書の検証において、その証明書がSSL/TLS通信を行うサーバーの身元を保証する目的で使用されることを示す定数です。

X.509証明書は、インターネット上での安全な通信、特にWebサイトへのアクセスやデータの送受信におけるセキュリティを確保するために広く利用されるデジタル証明書です。この証明書には、それがどのような用途や目的で利用されるべきかを示す情報が含まれており、これによって証明書の信頼性や適用範囲が定義されます。

このX509_PURPOSE_SSL_SERVER定数は、PHPのOpenSSL拡張機能と連携して動作します。具体的には、openssl_x509_checkpurpose() 関数などを用いて、あるX.509証明書が「SSL/TLSサーバー証明書」として適切であるかをプログラム的に検証する際に使用されます。例えば、ウェブブラウザがHTTPS接続でWebサイトにアクセスする際、サーバーが提示する証明書が本当にそのWebサイトのものであり、かつサーバーとして機能するための目的に合致しているかを確認するのと同様の検証を、PHPアプリケーション内で行うことが可能になります。

この定数を活用することで、アプリケーションは提示された証明書が意図された目的(SSLサーバーとしての利用)に適合しているかを厳密にチェックし、不正な証明書や目的外の証明書が使用されるのを防ぐことができます。これにより、通信の信頼性を高め、ユーザーに安全なWebサービスを提供する上で重要な役割を果たしています。

構文(syntax)

1<?php
2echo X509_PURPOSE_SSL_SERVER;
3?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

X509_PURPOSE_SSL_SERVER定数は、SSL/TLSサーバー証明書として使用できることを示す整数値を返します。

サンプルコード

PHP: X509_PURPOSE_SSL_SERVER で証明書目的を検証する

1<?php
2
3/**
4 * X509_PURPOSE_SSL_SERVER 定数を使用して、自己署名SSLサーバー証明書の目的を検証するサンプルコード。
5 *
6 * この関数は、システムエンジニアを目指す初心者向けに、PHPのOpenSSL拡張機能の
7 * X509_PURPOSE_SSL_SERVER 定数がどのように利用されるかを示します。
8 * 自己署名証明書を生成し、その証明書がSSLサーバーとして利用可能かを確認します。
9 *
10 * OpenSSL拡張機能が有効になっている必要があります。
11 */
12function demonstrateX509PurposeServer(): void
13{
14    echo "--- X509_PURPOSE_SSL_SERVER 定数のデモンストレーション ---\n\n";
15
16    // OpenSSL拡張機能が有効かチェック
17    if (!extension_loaded('openssl')) {
18        echo "エラー: OpenSSL拡張機能が有効ではありません。php.iniで 'extension=openssl' を有効にしてください。\n";
19        return;
20    }
21
22    // 証明書の生成に使用する一時ファイルのパスを初期化
23    $tempCertFile = null;
24    $privateKey = null;
25    $csr = null;
26    $x509 = null;
27
28    try {
29        // 1. 秘密鍵の生成のための設定
30        // RSA鍵を2048ビットで生成します。
31        $privateKeyConfig = [
32            "private_key_bits" => 2048,
33            "private_key_type" => OPENSSL_KEYTYPE_RSA,
34        ];
35
36        // 2. 秘密鍵の生成
37        echo "秘密鍵を生成しています...\n";
38        $privateKey = openssl_pkey_new($privateKeyConfig);
39        if (!$privateKey) {
40            throw new Exception("秘密鍵の生成に失敗しました: " . openssl_error_string());
41        }
42        echo "秘密鍵の生成に成功しました。\n";
43
44        // 3. CSR (証明書署名要求) の生成のための設定
45        // 主体者情報 (Subject Distinguished Name) を定義します。
46        $csrConfig = [
47            "countryName" => "JP",
48            "stateOrProvinceName" => "Tokyo",
49            "localityName" => "Shibuya-ku",
50            "organizationName" => "Example Corp",
51            "organizationalUnitName" => "IT Department",
52            "commonName" => "localhost", // サーバー証明書の場合、この値はサーバーのホスト名と一致する必要があります
53            "emailAddress" => "webmaster@localhost",
54            "digest_alg" => "sha256", // 署名アルゴリズム
55        ];
56
57        // 4. CSR (証明書署名要求) の生成
58        echo "CSR (証明書署名要求) を生成しています...\n";
59        $csr = openssl_csr_new($csrConfig, $privateKey);
60        if (!$csr) {
61            throw new Exception("CSRの生成に失敗しました: " . openssl_error_string());
62        }
63        echo "CSRの生成に成功しました。\n";
64
65        // 5. 自己署名証明書の生成
66        // 生成したCSRと秘密鍵を使用して、自己署名証明書を作成します。
67        // $days: 証明書の有効期限 (日数)
68        // $configargs: openssl.cnf の設定をオーバーライドする配列。
69        // ここでは、`extendedKeyUsage = serverAuth` を設定することで、
70        // この証明書がSSLサーバーとして利用できることを明示します。
71        echo "自己署名証明書を生成しています...\n";
72        $x509 = openssl_csr_sign(
73            $csr,
74            null, // 自己署名なのでCA証明書は指定しない (null)
75            $privateKey,
76            365, // 有効期間: 365日
77            [
78                'x509_extensions' => 'v3_req', // openssl.cnf の [v3_req] セクションを適用
79                'v3_req' => [
80                    'extendedKeyUsage' => 'serverAuth', // サーバー認証目的の拡張キー用法
81                    'subjectAltName' => 'DNS:localhost,IP:127.0.0.1' // 主体者代替名 (SAN)
82                ]
83            ]
84        );
85
86        if (!$x509) {
87            throw new Exception("自己署名証明書の生成に失敗しました: " . openssl_error_string());
88        }
89        echo "自己署名証明書の生成に成功しました。\n";
90
91        // 6. 証明書を一時ファイルに保存
92        // openssl_x509_checkpurpose はファイルパスを必要とするため、一時ファイルに保存します。
93        // tempnam はユニークな一時ファイル名を生成します。
94        $tempCertFile = tempnam(sys_get_temp_dir(), 'cert_');
95        if (!openssl_x509_export_to_file($x509, $tempCertFile)) {
96            throw new Exception("証明書の一時ファイルへの保存に失敗しました: " . openssl_error_string());
97        }
98        echo "一時証明書ファイル: " . $tempCertFile . "\n\n";
99
100        // 7. X509_PURPOSE_SSL_SERVER 定数を使用して証明書の目的をチェック
101        echo "定数 X509_PURPOSE_SSL_SERVER の値: " . X509_PURPOSE_SSL_SERVER . " (これは整数値です)\n";
102        echo "生成された証明書がSSLサーバー目的で有効かチェックします...\n";
103
104        // openssl_x509_checkpurpose は、指定された目的 (X509_PURPOSE_SSL_SERVER) に対して
105        // 証明書が適切に設定されているか (特に Key Usage や Extended Key Usage 拡張) を確認します。
106        $purposeResult = openssl_x509_checkpurpose($tempCertFile, X509_PURPOSE_SSL_SERVER);
107
108        if ($purposeResult === true) {
109            echo "結果: この証明書は **SSLサーバー目的で利用可能です。**\n";
110            echo "これは、証明書が 'extendedKeyUsage = serverAuth' を含んでいるためです。\n";
111        } elseif ($purposeResult === false) {
112            echo "結果: この証明書は **SSLサーバー目的で利用できません。**\n";
113            echo "OpenSSLエラー詳細:\n";
114            while ($msg = openssl_error_string()) {
115                echo "  - " . $msg . "\n";
116            }
117        } else { // -1 の場合
118            echo "結果: 証明書のチェック中にエラーが発生しました。\n";
119            echo "OpenSSLエラー詳細:\n";
120            while ($msg = openssl_error_string()) {
121                echo "  - " . $msg . "\n";
122            }
123        }
124
125    } catch (Exception $e) {
126        echo "致命的なエラー: " . $e->getMessage() . "\n";
127    } finally {
128        // 8. リソースの解放と一時ファイルの削除
129        // プログラムのどの段階でエラーが発生しても、確実にリソースを解放し、一時ファイルを削除します。
130        echo "\nリソースを解放し、一時ファイルを削除しています...\n";
131        if ($x509) {
132            openssl_x509_free($x509);
133        }
134        if ($csr) {
135            openssl_csr_free($csr);
136        }
137        if ($privateKey) {
138            openssl_pkey_free($privateKey);
139        }
140        if ($tempCertFile && file_exists($tempCertFile)) {
141            unlink($tempCertFile);
142            echo "一時証明書ファイルを削除しました。\n";
143        }
144        echo "デモンストレーション終了。\n";
145    }
146}
147
148// 関数を実行してデモンストレーションを開始
149demonstrateX509PurposeServer();
150
151?>

PHP 8のX509_PURPOSE_SSL_SERVER定数は、OpenSSL拡張機能の一部であり、X.509証明書がSSLサーバーとして利用可能かどうかを検証する目的を示すために使用されます。この定数自体は引数を持たず、証明書の目的を示す整数値として定義されています。

サンプルコードでは、まずOpenSSL拡張機能が有効であることを確認し、自己署名SSLサーバー証明書を生成する一連の手順を示しています。具体的には、RSA秘密鍵とCSR(証明書署名要求)を作成し、extendedKeyUsage = serverAuthというSSLサーバー用途を示す拡張を含む自己署名証明書を生成し、一時ファイルに保存しています。

その後、openssl_x509_checkpurpose関数に、一時ファイルに保存された証明書のパスとX509_PURPOSE_SSL_SERVER定数を渡して、証明書がSSLサーバーとして適切に機能するかどうかをチェックしています。この関数は、証明書内のキー使用法や拡張キー使用法といった情報を確認し、目的と合致するかどうかを判定します。openssl_x509_checkpurposeの戻り値は、目的と合致すればtrue、合致しなければfalse、エラーが発生した場合は-1となります。このように、X509_PURPOSE_SSL_SERVER定数を利用することで、プログラム的に証明書の用途を安全に検証できるようになります。

このサンプルコードは、PHPのOpenSSL拡張機能でX509_PURPOSE_SSL_SERVER定数を利用し、証明書がSSLサーバー用途に適しているかを確認するものです。まず、OpenSSL拡張機能がphp.iniで有効になっているか必ず確認してください。自己署名証明書は開発・テスト用であり、本番環境では信頼できる認証局の証明書を利用する必要があります。証明書をSSLサーバー目的で使うためには、生成時にextendedKeyUsage = serverAuthを正しく設定することが重要です。秘密鍵や証明書は重要な情報のため、一時ファイルの生成や削除を含め、取り扱いには細心の注意を払い、エラー発生時にも確実にリソースを解放するよう習慣づけましょう。

PHP X509CertificateでSSLサーバー証明書用途をチェックする

1<?php
2
3/**
4 * 指定されたPEM形式のX.509証明書がSSLサーバー用途に適しているかをチェックします。
5 * X509_PURPOSE_SSL_SERVER 定数を使用して検証を行います。
6 * この定数は、PHPのOpenSSL拡張機能によって提供され、
7 * 証明書が特定の目的に合致するかどうかを判定する際に利用される整数値です。
8 *
9 * @param string $certificatePem PEM形式の証明書文字列
10 * @return void
11 */
12function checkSslServerCertificatePurpose(string $certificatePem): void
13{
14    // OpenSSL拡張が有効か確認します。
15    // 無効な場合、関連する関数や定数は利用できません。
16    if (!extension_loaded('openssl')) {
17        echo "エラー: OpenSSL拡張が有効になっていません。php.iniで有効にしてください。\n";
18        return;
19    }
20
21    // PEM形式の文字列からX.509証明書リソースを読み込みます。
22    // openssl_x509_read() は、成功するとX.509リソース、失敗するとfalseを返します。
23    $x509Resource = openssl_x509_read($certificatePem);
24
25    if ($x509Resource === false) {
26        echo "エラー: 証明書の読み込みに失敗しました。無効なPEM形式の可能性があります。\n";
27        // OpenSSLライブラリからの詳細なエラー情報を取得します。
28        while (($error = openssl_error_string()) !== false) {
29            echo "OpenSSLエラー: " . $error . "\n";
30        }
31        return;
32    }
33
34    // X509_PURPOSE_SSL_SERVER 定数を使用して、証明書がSSLサーバー用途に適しているかチェックします。
35    // openssl_x509_checkpurpose() は、証明書のExtended Key Usage (拡張鍵用途) などの情報を検証します。
36    // 戻り値:
37    //   1: 証明書は目的 (SSLサーバー) に適している
38    //   0: 証明書は目的 (SSLサーバー) に適していない
39    //  -1: チェック中にエラーが発生した、または目的を判断できなかった
40    $result = openssl_x509_checkpurpose($x509Resource, X509_PURPOSE_SSL_SERVER);
41
42    echo "証明書のSSLサーバー用途チェック結果: ";
43    if ($result === 1) {
44        echo "✓ 適しています。\n";
45    } elseif ($result === 0) {
46        echo "✗ 適していません。\n";
47        while (($error = openssl_error_string()) !== false) {
48            echo "OpenSSLエラー: " . $error . "\n";
49        }
50    } elseif ($result === -1) {
51        echo "? チェック中にエラーが発生しました、または目的を判断できませんでした。\n";
52        while (($error = openssl_error_string()) !== false) {
53            echo "OpenSSLエラー: " . $error . "\n";
54        }
55    } else {
56        // 予期せぬ結果の場合 (通常は発生しないはず)
57        echo "未知の応答 (" . $result . ")\n";
58    }
59
60    // X.509証明書リソースを解放します。
61    openssl_x509_free($x509Resource);
62}
63
64// --- 実際の使用例 ---
65// システムエンジニアを目指す初心者が、このコードを手元ですぐに実行できるように、
66// 有効な自己署名証明書をコード内で一時的に生成し、その目的をチェックします。
67// これにより、外部ファイルを用意する手間なく「単体で動作可能」となります。
68
69// OpenSSL拡張が有効か最終確認
70if (!extension_loaded('openssl')) {
71    echo "致命的エラー: OpenSSL拡張が有効になっていません。php.iniで有効にしてください。\n";
72    exit(1); // 実行を停止
73}
74
75echo "--- テスト用の自己署名証明書を生成し、目的をチェックします ---\n";
76
77// 1. 秘密鍵の生成
78$privateKey = openssl_pkey_new([
79    "private_key_bits" => 2048,           // 鍵の長さ (ビット)
80    "private_key_type" => OPENSSL_KEYTYPE_RSA, // 鍵の種類 (RSA)
81]);
82if ($privateKey === false) {
83    echo "エラー: 秘密鍵の生成に失敗しました。\n";
84    exit(1);
85}
86
87// 2. 証明書署名要求 (CSR) の詳細情報
88// これはテスト目的のダミー情報です。
89$csrDetails = [
90    "countryName" => "JP",
91    "stateOrProvinceName" => "Tokyo",
92    "localityName" => "Shinjuku-ku",
93    "organizationName" => "Example Corp",
94    "organizationalUnitName" => "IT Division",
95    "commonName" => "localhost", // SSLサーバー証明書ではCommon Name (コモンネーム) が重要
96    "emailAddress" => "admin@localhost.com",
97];
98
99// 3. CSR (Certificate Signing Request) の生成
100// Extended Key Usage (拡張鍵用途) に 'serverAuth' を含めることで、
101// SSLサーバー用途に適した証明書になるようにします。
102$csr = openssl_csr_new($csrDetails, $privateKey, [
103    "digest_alg" => "sha256", // ハッシュアルゴリズム
104    "x509_extensions" => [
105        "basicConstraints" => "CA:FALSE", // この証明書は認証局ではない
106        "keyUsage" => "digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment",
107        "extendedKeyUsage" => "serverAuth, clientAuth", // ここが重要: serverAuth を含める
108        "subjectAltName" => "DNS:localhost,IP:127.0.0.1" // サブジェクト代替名
109    ]
110]);
111if ($csr === false) {
112    echo "エラー: CSRの生成に失敗しました。\n";
113    openssl_pkey_free($privateKey);
114    exit(1);
115}
116
117// 4. 自己署名証明書の生成
118// CSRと秘密鍵を使用して、自分自身で署名した証明書を生成します。
119// 有効期間を7日間 (604800秒) に設定。
120$certificateResource = openssl_csr_sign($csr, null, $privateKey, $days = 7, [
121    "digest_alg" => "sha256",
122    "x509_extensions" => [
123        "basicConstraints" => "CA:FALSE",
124        "keyUsage" => "digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment",
125        "extendedKeyUsage" => "serverAuth, clientAuth", // ここが重要: serverAuth を含める
126        "subjectAltName" => "DNS:localhost,IP:127.0.0.1"
127    ]
128]);
129if ($certificateResource === false) {
130    echo "エラー: 自己署名証明書の生成に失敗しました。\n";
131    openssl_pkey_free($privateKey);
132    exit(1);
133}
134
135// 5. 生成された証明書をPEM形式の文字列として取得
136$generatedCertificatePem = '';
137openssl_x509_export($certificateResource, $generatedCertificatePem);
138
139// 生成した証明書を使ってチェック関数を呼び出す
140checkSslServerCertificatePurpose($generatedCertificatePem);
141
142// 生成したリソースを解放
143openssl_x509_free($certificateResource);
144openssl_pkey_free($privateKey);
145
146echo "\n--- SSLサーバー用途に適さない証明書でチェックを実行します ---\n";
147// (Extended Key Usageに 'serverAuth' を含まない証明書を作成する例)
148
149$privateKey2 = openssl_pkey_new(); // 新しい秘密鍵を生成
150if ($privateKey2 === false) {
151    echo "エラー: 2番目の秘密鍵の生成に失敗しました。\n";
152    exit(1);
153}
154
155// Extended Key Usage から "serverAuth" を意図的に削除してCSRと証明書を生成
156$csr2 = openssl_csr_new($csrDetails, $privateKey2, [
157    "digest_alg" => "sha256",
158    "x509_extensions" => [
159        "basicConstraints" => "CA:FALSE",
160        "keyUsage" => "digitalSignature",
161        // extendedKeyUsage を設定しないか、serverAuth を含めない
162        // "extendedKeyUsage" => "clientAuth", // 例としてclientAuthのみ
163    ]
164]);
165
166$certificateResource2 = openssl_csr_sign($csr2, null, $privateKey2, $days = 7, [
167    "digest_alg" => "sha256",
168    "x509_extensions" => [
169        "basicConstraints" => "CA:FALSE",
170        "keyUsage" => "digitalSignature",
171        // extendedKeyUsage を設定しないか、serverAuth を含めない
172        // "extendedKeyUsage" => "clientAuth",
173    ]
174]);
175
176if ($certificateResource2 !== false) {
177    $generatedCertificatePem2 = '';
178    openssl_x509_export($certificateResource2, $generatedCertificatePem2);
179    checkSslServerCertificatePurpose($generatedCertificatePem2); // 通常は「適していません」と表示される
180    openssl_x509_free($certificateResource2);
181} else {
182    echo "エラー: 2番目の自己署名証明書の生成に失敗しました。\n";
183}
184openssl_pkey_free($privateKey2);
185
186?>

このPHPサンプルコードは、X.509証明書がSSLサーバーとしての利用に適しているかを検証する方法を示しています。X509_PURPOSE_SSL_SERVERは、PHPのOpenSSL拡張機能が提供する定数で、証明書がSSLサーバー用途に合致するかを判定する際に使用される整数値です。

コードの中心となるcheckSslServerCertificatePurpose関数は、まず引数として渡されたPEM形式の証明書文字列をopenssl_x509_read()関数で読み込み、証明書リソースを取得します。この関数は成功すると証明書リソースを、失敗するとfalseを返します。次に、openssl_x509_checkpurpose()関数を使用し、取得した証明書リソースとX509_PURPOSE_SSL_SERVER定数を渡して証明書の目的をチェックします。この関数は、証明書が目的に適していれば1、適していなければ0、チェック中にエラーが発生した場合は-1を返します。これらの結果に基づいて、適切なメッセージを出力し、OpenSSLライブラリからのエラー情報はopenssl_error_string()で取得・表示しています。

コード後半では、X509_PURPOSE_SSL_SERVERの動作を実際に確認できるよう、自己署名証明書を動的に生成しています。特に、証明書の拡張鍵用途(Extended Key Usage)にserverAuthを含めるか否かで、openssl_x509_checkpurpose()関数の結果がどのように変わるかを示しており、初心者がこの定数の意味と用途を理解するのに役立ちます。

PHPのX509_PURPOSE_SSL_SERVER定数を利用するには、php.iniでOpenSSL拡張を有効にする必要があります。有効でない場合、関連関数や定数は利用できません。この定数を用いるopenssl_x509_checkpurpose()関数は、証明書の拡張鍵用途などを確認し、SSLサーバーとしての利用可否を判断します。戻り値が1以外(0や-1)の場合は、証明書が目的に適していないか、エラーが発生していますので、openssl_error_string()で詳細なエラー情報を必ず確認してください。サンプルコードでの証明書生成はテスト用です。本番環境では、安全に取得・管理された証明書と秘密鍵を使用し、利用後はopenssl_x509_free()などでリソースを確実に解放することが重要です。

関連コンテンツ

関連IT用語

関連プログラミング言語