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

【PHP8.x】openssl_x509_check_private_key()関数の使い方

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

作成日: 更新日:

基本的な使い方

openssl_x509_check_private_key関数は、X.509形式のデジタル証明書とそれに対応する秘密鍵が正しく関連付けられているかを検証する関数です。X.509証明書は、ウェブサイトやサービスなどのエンティティの身元を保証するために使用されるデジタルファイルであり、秘密鍵はその証明書と対になる非常に重要な鍵です。この関数は、引数として渡されたX.509証明書と秘密鍵の内容を検査し、それらが本当に一致するペアであるかどうかを確認します。具体的には、秘密鍵を使用して証明書が正しく署名されているかを検証することで、両者の整合性を確認します。検証の結果、証明書と秘密鍵が一致する有効なペアであればtrue(真)を返し、一致しない場合や検証に失敗した場合はfalse(偽)を返します。この機能は、SSL/TLSなどのセキュアな通信環境を構築する際に不可欠です。例えば、ウェブサーバーにSSL証明書を設定する際、提供された証明書と秘密鍵が意図した正しい組み合わせであるかを事前に確認できます。これにより、誤った鍵の組み合わせによる設定エラーを防ぎ、通信の信頼性とセキュリティを確保するために役立ちます。

構文(syntax)

1<?php
2openssl_x509_check_private_key($certificate, $privateKey);

引数(parameters)

OpenSSLCertificate|string $certificate, OpenSSLAsymmetricKey|string $private_key

  • OpenSSLCertificate|string $certificate: 検証するX.509証明書。OpenSSLCertificateオブジェクトまたは証明書を表す文字列を指定します。
  • OpenSSLAsymmetricKey|string $private_key: 証明書に対応する秘密鍵。OpenSSLAsymmetricKeyオブジェクトまたは秘密鍵を表す文字列を指定します。

戻り値(return)

bool

指定された証明書 (X.509) が、指定された秘密鍵と対応しているかどうかを判定します。対応している場合は true を、対応していない場合やエラーが発生した場合は false を返します。

サンプルコード

openssl_x509_check_private_key で証明書とキーを検証する

1<?php
2
3/**
4 * 自己署名証明書とプライベートキーを生成し、そのペアが一致するか検証します。
5 * この関数は、証明書とプライベートキーのペアリングを確認する openssl_x509_check_private_key 関数と、
6 * ファイルからプライベートキーを読み込む openssl_pkey_get_private 関数の使用例を示します。
7 *
8 * システムエンジニアを目指す初心者向けに、各ステップで何が行われているかをコメントで説明しています。
9 *
10 * @return void
11 */
12function demonstrateOpensslKeyVerification(): void
13{
14    echo "--- 1. 自己署名証明書とプライベートキーの生成 ---" . PHP_EOL;
15
16    // 1. 新しいプライベートキーを生成します。
17    // 主にRSA鍵を生成し、ビット数やハッシュアルゴリズムを指定します。
18    $privateKeyConfig = [
19        "digest_alg" => "sha256",          // 署名に使用するハッシュアルゴリズム
20        "private_key_bits" => 2048,        // キーのビット長(強度)
21        "private_key_type" => OPENSSL_KEYTYPE_RSA, // キーの種類(RSA)
22    ];
23    $privateKeyResource = openssl_pkey_new($privateKeyConfig);
24
25    if (!$privateKeyResource) {
26        echo "エラー: プライベートキーの生成に失敗しました。" . PHP_EOL;
27        return;
28    }
29    echo "新しいプライベートキーが生成されました。" . PHP_EOL;
30
31    // 生成したプライベートキーをPEM形式の文字列にエクスポートします。
32    // PEM形式は、OpenSSLがファイルを扱う際の標準的なテキスト形式です。
33    openssl_pkey_export($privateKeyResource, $privateKeyPem);
34
35    // 2. 証明書署名要求 (CSR) を生成します。
36    // CSRは、証明書を発行してもらうために認証局(CA)に送る情報です。
37    // この例では自己署名なので、CAは使いません。
38    $csrConfig = [
39        "countryName" => "JP",
40        "stateOrProvinceName" => "Tokyo",
41        "localityName" => "Shinjuku",
42        "organizationName" => "Example Corp",
43        "commonName" => "example.com", // 証明書の対象となるホスト名
44        "emailAddress" => "admin@example.com",
45    ];
46    $csrResource = openssl_csr_new($csrConfig, $privateKeyResource, $privateKeyConfig);
47
48    if (!$csrResource) {
49        echo "エラー: CSRの生成に失敗しました。" . PHP_EOL;
50        return;
51    }
52    echo "証明書署名要求 (CSR) が生成されました。" . PHP_EOL;
53
54    // 3. 自己署名証明書を生成します。
55    // CAを使わずに、自分自身で署名する証明書です。検証用によく使われます。
56    // 証明書の有効期間を365日に設定しています。
57    $certificateResource = openssl_csr_sign($csrResource, null, $privateKeyResource, 365, $privateKeyConfig);
58
59    if (!$certificateResource) {
60        echo "エラー: 自己署名証明書の生成に失敗しました。" . PHP_EOL;
61        return;
62    }
63    echo "自己署名証明書が生成されました。" . PHP_EOL;
64
65    // 生成した証明書をPEM形式の文字列にエクスポートします。
66    openssl_x509_export($certificateResource, $certificatePem);
67
68
69    echo PHP_EOL . "--- 2. openssl_x509_check_private_key による検証 ---" . PHP_EOL;
70
71    // openssl_x509_check_private_key 関数を使用して、
72    // 証明書とプライベートキーが正しくペアになっているかを確認します。
73    // この関数は、証明書と秘密鍵が論理的に一致する場合に true を返します。
74    // 引数にはOpenSSLリソースまたはPEM形式の文字列を渡すことができます。
75
76    // リソース形式で検証
77    $isMatchResource = openssl_x509_check_private_key($certificateResource, $privateKeyResource);
78
79    if ($isMatchResource) {
80        echo "検証結果: 証明書とプライベートキーは一致します。(OpenSSLリソース使用)" . PHP_EOL;
81    } else {
82        echo "検証結果: 証明書とプライベートキーは一致しません。(OpenSSLリソース使用)" . PHP_EOL;
83        // エラーが発生した場合、openssl_error_string() で詳細を確認できます。
84        while ($msg = openssl_error_string()) {
85            echo "OpenSSLエラー: " . $msg . PHP_EOL;
86        }
87    }
88
89    // PEM文字列形式で検証
90    $isMatchPem = openssl_x509_check_private_key($certificatePem, $privateKeyPem);
91
92    if ($isMatchPem) {
93        echo "検証結果: 証明書とプライベートキーは一致します。(PEM文字列使用)" . PHP_EOL;
94    } else {
95        echo "検証結果: 証明書とプライベートキーは一致しません。(PEM文字列使用)" . PHP_EOL;
96    }
97
98
99    echo PHP_EOL . "--- 3. キーワードに関連する openssl_pkey_get_private の使用例 ---" . PHP_EOL;
100
101    // openssl_pkey_get_private 関数は、ファイルや文字列からプライベートキーを読み込み、
102    // OpenSSLAsymmetricKey リソースとして返すために使用されます。
103    // これは、既存のキーファイルをプログラムで扱う際に非常に重要です。
104
105    // 例として、生成したプライベートキーを一時ファイルに保存し、そこから読み込み直します。
106    $tempKeyFile = tempnam(sys_get_temp_dir(), 'pkey_'); // 一時ファイルのパスを生成
107    if ($tempKeyFile === false) {
108        echo "エラー: 一時ファイルの作成に失敗しました。" . PHP_EOL;
109        return;
110    }
111    file_put_contents($tempKeyFile, $privateKeyPem); // PEM形式のキーをファイルに書き込む
112
113    echo "プライベートキーを一時ファイル '{$tempKeyFile}' に保存しました。" . PHP_EOL;
114
115    // ファイルの内容を読み込み、openssl_pkey_get_private でプライベートキーリソースを取得
116    $loadedPrivateKeyResource = openssl_pkey_get_private(file_get_contents($tempKeyFile));
117
118    if ($loadedPrivateKeyResource) {
119        echo "openssl_pkey_get_private でプライベートキーをファイルから正常に読み込みました。" . PHP_EOL;
120
121        // 読み込んだプライベートキーを使用して、再度証明書とのペアリングを検証します。
122        $isMatchLoadedKey = openssl_x509_check_private_key($certificateResource, $loadedPrivateKeyResource);
123        if ($isMatchLoadedKey) {
124            echo "検証結果: 読み込んだプライベートキーと証明書は一致します。" . PHP_EOL;
125        } else {
126            echo "検証結果: 読み込んだプライベートキーと証明書は一致しません。" . PHP_EOL;
127        }
128    } else {
129        echo "エラー: openssl_pkey_get_private でプライベートキーの読み込みに失敗しました。" . PHP_EOL;
130        while ($msg = openssl_error_string()) {
131            echo "OpenSSLエラー: " . $msg . PHP_EOL;
132        }
133    }
134
135    // 作成した一時ファイルをクリーンアップします。
136    if (file_exists($tempKeyFile)) {
137        unlink($tempKeyFile);
138        echo "一時ファイル '{$tempKeyFile}' を削除しました。" . PHP_EOL;
139    }
140
141    // OpenSSL リソースはPHPのガベージコレクションによって自動的に解放されますが、
142    // 大量の操作を行う場合や古いPHPバージョンでは明示的に解放することも検討されます。
143    // openssl_pkey_free($privateKeyResource);
144    // openssl_x509_free($certificateResource);
145    // openssl_pkey_free($loadedPrivateKeyResource);
146}
147
148// 関数を実行して、一連の処理を確認します。
149demonstrateOpensslKeyVerification();
150
151?>

PHP 8のopenssl_x509_check_private_key関数は、X.509証明書とプライベートキーが互いに対応するペアであるかを検証するために使用されます。これは、ウェブサーバーなどで使用するSSL/TLS証明書が、正しい秘密鍵で署名されているかを確認する際に非常に重要な機能です。

この関数は、第1引数に証明書データをOpenSSLCertificateリソースまたはPEM形式の文字列として、第2引数にプライベートキーデータをOpenSSLAsymmetricKeyリソースまたはPEM形式の文字列として受け取ります。そして、これらが一致するペアであればtrueを、そうでなければfalseを論理値として返します。

サンプルコードでは、まずopenssl_pkey_newなどで自己署名証明書とプライベートキーを生成しています。次に、生成した証明書とプライベートキーをopenssl_x509_check_private_keyに渡し、両者が一致することを確認しています。

また、関連するopenssl_pkey_get_private関数も紹介されています。この関数は、ファイルなどからPEM形式のプライベートキーデータを読み込み、OpenSSLAsymmetricKeyリソースとして取得するために使われます。サンプルでは、一時ファイルに保存されたプライベートキーをopenssl_pkey_get_privateで読み込み、その読み込んだキーが証明書と一致するかを再度openssl_x509_check_private_keyで検証する実用的な手順が示されています。これにより、システムエンジニアが証明書と秘密鍵の整合性をプログラムで確認する基本的な方法を理解できます。

このサンプルコードは、PHPでOpenSSLの鍵ペア検証の仕組みを学ぶ上で有効です。本番環境で秘密鍵を扱う際は、厳重な管理とパスフレーズによる保護が必須です。また、この自己署名証明書は開発・テスト用であり、実際のシステムでは信頼できる認証局(CA)発行の証明書を使用してください。機能を利用するには、PHPのopensslエクステンションが有効である必要があります。処理中のエラーはopenssl_error_string()で確認し、一時ファイルは必ず削除するなど、セキュリティとリソース管理に十分注意してください。

openssl_x509_check_private_key で証明書と鍵を検証する

1<?php
2
3/**
4 * 自己署名証明書と秘密鍵を生成します。
5 *
6 * openssl_x509_check_private_key 関数で検証するために必要な証明書と秘密鍵のペアを作成します。
7 *
8 * @return array{privateKey: OpenSSLAsymmetricKey|false, certificate: OpenSSLCertificate|false}
9 *         生成された秘密鍵と証明書、または失敗した場合は false を含む配列。
10 */
11function generateSelfSignedCertAndKey(): array
12{
13    // 1. 秘密鍵を生成
14    // 2048ビットのRSA鍵を作成します。
15    $privateKey = openssl_pkey_new([
16        'private_key_bits' => 2048,
17        'private_key_type' => OPENSSL_KEYTYPE_RSA,
18    ]);
19
20    if (!$privateKey) {
21        echo "エラー: 秘密鍵の生成に失敗しました。\n";
22        return ['privateKey' => false, 'certificate' => false];
23    }
24
25    // 2. 証明書署名要求 (CSR) の情報を設定
26    // 証明書に含まれる情報(例: 組織名、ドメイン名など)を定義します。
27    $csrConfig = [
28        'countryName' => 'JP',
29        'stateOrProvinceName' => 'Tokyo',
30        'localityName' => 'Shinjuku',
31        'organizationName' => 'Example Inc.',
32        'organizationalUnitName' => 'IT',
33        'commonName' => 'example.com',
34        'emailAddress' => 'admin@example.com',
35    ];
36
37    // 3. CSRを生成
38    // 上記の情報と生成した秘密鍵を使用してCSRを作成します。
39    $csr = openssl_csr_new($csrConfig, $privateKey, [
40        'digest_alg' => 'sha256' // 署名に使用するハッシュアルゴリズム
41    ]);
42
43    if (!$csr) {
44        echo "エラー: CSRの生成に失敗しました。\n";
45        return ['privateKey' => false, 'certificate' => false];
46    }
47
48    // 4. CSRを自己署名して証明書を生成
49    // 生成したCSRを自分自身の秘密鍵で署名することで、自己署名証明書を作成します。
50    // 有効期間は365日とします。
51    $certificate = openssl_csr_sign($csr, null, $privateKey, 365, [
52        'digest_alg' => 'sha256'
53    ]);
54
55    if (!$certificate) {
56        echo "エラー: 証明書の生成に失敗しました。\n";
57        return ['privateKey' => false, 'certificate' => false];
58    }
59
60    return ['privateKey' => $privateKey, 'certificate' => $certificate];
61}
62
63// 自己署名証明書と秘密鍵を生成
64echo "--- 証明書と秘密鍵の生成を開始 ---\n";
65$keyPair = generateSelfSignedCertAndKey();
66$generatedPrivateKey = $keyPair['privateKey'];
67$generatedCertificate = $keyPair['certificate'];
68
69if (!$generatedPrivateKey || !$generatedCertificate) {
70    echo "鍵と証明書の生成に失敗したため、検証を実行できません。\n";
71    exit(1);
72}
73echo "--- 証明書と秘密鍵の生成が完了 ---\n\n";
74
75echo "--- openssl_x509_check_private_key 関数による検証 ---\n";
76
77// 1. 生成した正しい証明書と秘密鍵のペアをチェック
78echo "シナリオ1: 正しい証明書と秘密鍵のペアを検証中...\n";
79if (openssl_x509_check_private_key($generatedCertificate, $generatedPrivateKey)) {
80    echo "結果: 成功 - 証明書と秘密鍵は正しく一致しています。\n";
81} else {
82    echo "結果: 失敗 - 証明書と秘密鍵が一致しませんでした。(これは予期しない結果です)\n";
83}
84echo "\n";
85
86// 2. 意図的に異なる秘密鍵を用意してチェック
87echo "シナリオ2: 証明書と一致しない異なる秘密鍵のペアを検証中...\n";
88// 検証用に、元の証明書とは無関係な新しい秘密鍵を生成します。
89$wrongPrivateKey = openssl_pkey_new([
90    'private_key_bits' => 1024, // 異なるビット数で生成
91    'private_key_type' => OPENSSL_KEYTYPE_RSA,
92]);
93
94if (!$wrongPrivateKey) {
95    echo "エラー: 異なる秘密鍵の生成に失敗しました。\n";
96} else {
97    if (openssl_x509_check_private_key($generatedCertificate, $wrongPrivateKey)) {
98        echo "結果: 失敗 - 異なる鍵なのに一致と判定されました。(これは予期しない結果です)\n";
99    } else {
100        echo "結果: 成功 - 証明書と異なる秘密鍵は一致していません。(これは期待される正しい結果です)\n";
101    }
102}
103echo "\n";
104
105// PHP 8以降では、OpenSSLAsymmetricKeyおよびOpenSSLCertificateオブジェクトは自動的にメモリ管理されるため、
106// 明示的なクローズや解放は通常不要です。
107?>

openssl_x509_check_private_key関数は、指定された証明書と秘密鍵が互いに正しいペアであるかを確認する際に使用します。これは、WebサーバーのSSL/TLS設定などで、証明書と秘密鍵の対応関係が正しいかを検証する際に役立つ機能です。

引数としては、第一引数に検証したい「証明書」(OpenSSLCertificateオブジェクトまたはPEM形式の文字列)を、第二引数にその証明書に対応すると考えられる「秘密鍵」(OpenSSLAsymmetricKeyオブジェクトまたはPEM形式の文字列)を渡します。戻り値は真偽値(bool)で、両者が正しくペアであればtrueを、一致しない場合や検証に失敗した場合はfalseを返します。

このサンプルコードでは、まず検証のために、openssl_pkey_newなどで自己署名証明書と秘密鍵のペアを生成しています。最初の検証では、生成した正しい証明書と秘密鍵のペアをopenssl_x509_check_private_key関数に渡しており、期待通り「一致している」という結果(true)が得られます。次に、意図的に異なる秘密鍵を生成し、元の証明書と一致しない組み合わせで検証を行っています。この場合、関数は「一致していない」という結果(false)を返し、異なる鍵であることを正しく識別できることを示しています。これにより、証明書と秘密鍵の整合性を容易に確認できます。

openssl_x509_check_private_key関数は、公開鍵証明書と秘密鍵が正しくペアになっているかを確認するために利用します。サンプルコードでは自己署名証明書を生成していますが、実際のシステムでは認証局(CA)が発行した信頼できる証明書を利用することが一般的です。証明書や鍵の生成過程でエラーが発生した場合は、openssl_error_string()関数で詳細なエラーメッセージを確認すると原因究明に役立ちます。PHP 8以降では、引数にOpenSSLCertificateOpenSSLAsymmetricKeyオブジェクトを直接渡せるようになり、安全かつ簡単に取り扱えます。鍵のビット数などセキュリティ関連のパラメータは、用途に応じて適切な値を慎重に選択してください。

関連コンテンツ

関連IT用語

関連プログラミング言語