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

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

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

作成日: 更新日:

基本的な使い方

CURLOPT_PROXY_PINNEDPUBLICKEY定数は、PHPのcURL拡張機能において、プロキシサーバーを介した通信のセキュリティを強化するための設定を表す定数です。この定数を使用することで、プロキシサーバーとのSSL/TLS通信を行う際に、接続先のプロキシサーバーが信頼できる正規のものであるかを検証する「公開鍵ピンニング」というセキュリティメカニズムを有効にできます。

具体的には、通信を行う前に、アクセスしたいプロキシサーバーのSSL/TLS証明書から抽出した公開鍵のハッシュ値などの情報を、このオプションの引数としてcurl_setopt()関数に設定します。cURLは通信開始時に、実際にプロキシサーバーから提示された証明書の公開鍵が、事前に設定した情報と一致するかどうかを確認します。もし一致しない場合は、接続を拒否し、通信が中断されます。

これにより、悪意のある第三者が正規のプロキシサーバーになりすまして通信を傍受しようとする「中間者攻撃」などの脅威から、通信の安全性を保護することが可能になります。このオプションの引数には、公開鍵のSHA256ハッシュ値や、DER形式の証明書ファイルを指定することができます。システム開発において、プロキシ経由で重要なデータをやり取りする際には、この定数を用いてセキュリティを一層強化することが推奨されます。

構文(syntax)

1<?php
2$ch = curl_init();
3curl_setopt($ch, CURLOPT_PROXY_PINNEDPUBLICKEY, 'sha256//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=');
4?>

引数(parameters)

引数なし

引数はありません

戻り値(return)

int

この定数は、プロキシサーバーの証明書検証に使用する公開鍵のピンニング情報を指定するために使用され、整数値を返します。

サンプルコード

PHP curlopt_proxy公開鍵設定で通信する

1<?php
2
3declare(strict_types=1);
4
5/**
6 * プロキシサーバーの公開鍵を検証するCURLオプションの設定例
7 *
8 * この関数は、CURLOPT_PROXY_PINNEDPUBLICKEY オプションの使用方法を示します。
9 * プロキシサーバーの公開鍵を指定して、中間者攻撃(Man-in-the-middle attack)を防ぐのに役立ちます。
10 *
11 * @param string $url 検証対象のURL
12 * @param string $proxy_url 使用するプロキシサーバーのURL (例: "http://localhost:8888")
13 * @param string $public_key_path プロキシサーバーの公開鍵(PEM形式)へのパス
14 * @return string|false 成功した場合は取得したコンテンツ、失敗した場合はfalse
15 */
16function fetchWithProxyPinnedPublicKey(
17    string $url,
18    string $proxy_url,
19    string $public_key_path
20): string|false {
21    $ch = curl_init();
22
23    if ($ch === false) {
24        // CURLセッションの初期化に失敗した場合
25        echo "エラー: CURLセッションの初期化に失敗しました。\n";
26        return false;
27    }
28
29    // CURLオプションを設定
30    curl_setopt($ch, CURLOPT_URL, $url);
31    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 結果を文字列で取得
32
33    // プロキシサーバーを設定
34    curl_setopt($ch, CURLOPT_PROXY, $proxy_url);
35
36    // CURLOPT_PROXY_PINNEDPUBLICKEY の設定
37    // このオプションは、プロキシサーバーの公開鍵を検証するために使用されます。
38    // 指定されたパスには、プロキシサーバーの実際の公開鍵ファイル(PEM形式)へのパスを指定する必要があります。
39    // 例: "sha256//<base64_encoded_sha256_hash>" 形式も可能ですが、ここではファイルパスの例を示します。
40    curl_setopt($ch, CURLOPT_PROXY_PINNEDPUBLICKEY, $public_key_path);
41
42    // プロキシ経由のSSL/TLS通信時に、ホストの証明書検証をスキップする場合(開発環境など)
43    // 本番環境ではセキュリティリスクがあるため、推奨されません。
44    // curl_setopt($ch, CURLOPT_PROXY_SSL_VERIFYPEER, false);
45    // curl_setopt($ch, CURLOPT_PROXY_SSL_VERIFYHOST, 0);
46
47    $response = curl_exec($ch);
48
49    if ($response === false) {
50        // CURL実行中にエラーが発生した場合
51        $error_message = curl_error($ch);
52        $error_code = curl_errno($ch);
53        echo "CURLエラー発生: [{$error_code}] {$error_message}\n";
54    } else {
55        echo "CURLリクエストが成功しました。\n";
56        echo "レスポンスの先頭200文字:\n";
57        echo substr($response, 0, 200) . "...\n";
58    }
59
60    curl_close($ch); // CURLセッションを終了
61
62    return $response;
63}
64
65// --- サンプル実行 ---
66// このコードを実際に動作させるには、有効なプロキシサーバーと、
67// そのプロキシサーバーの公開鍵ファイル(PEM形式)が必要です。
68// この例では、架空のプロキシURLと公開鍵ファイルのパスを使用しているため、
69// 実行すると通常は接続エラーまたは検証エラーが発生します。
70
71$target_url = "https://example.com";
72$proxy_address = "http://localhost:8888"; // 例: Fiddler, Charles Proxy などが動作しているプロキシURL
73$public_key_file_path = __DIR__ . '/proxy_public_key.pem'; // このパスに実際の公開鍵ファイルを配置してください
74
75// 公開鍵ファイルが存在するか確認
76if (!file_exists($public_key_file_path)) {
77    echo "エラー: プロキシ公開鍵ファイル '{$public_key_file_path}' が見つかりません。\n";
78    echo "このサンプルコードを実行するには、このパスにPEM形式の公開鍵ファイルを配置してください。\n";
79    echo "ヒント: openssl genrsa -out private.key 2048 && openssl rsa -in private.key -pubout -out public.key でpublic.keyファイルを生成できます。\n";
80    exit(1); // ファイルがない場合は終了
81}
82
83echo "CURLリクエストを送信中...\n";
84fetchWithProxyPinnedPublicKey($target_url, $proxy_address, $public_key_file_path);

このPHPサンプルコードは、CURLOPT_PROXY_PINNEDPUBLICKEYオプションを用いて、プロキシサーバーの公開鍵を検証しながらHTTPリクエストを実行する方法を初心者の方にもわかりやすく示しています。このオプションは、指定されたプロキシサーバーの公開鍵が、実際に通信しようとしているプロキシサーバーの公開鍵と一致するかどうかを確認することで、中間者攻撃(Man-in-the-middle attack)のようなセキュリティ上の脅威を防ぐ重要な役割を果たします。

fetchWithProxyPinnedPublicKey関数は、ターゲットとなる$urlへ、$proxy_urlで指定されたプロキシサーバーを経由してアクセスします。特に、$public_key_pathにはプロキシサーバーの公開鍵が保存されたPEM形式のファイルパスを指定し、この鍵情報を使ってプロキシ接続の信頼性を確保します。

関数内では、まずcurl_init()でCURLセッションを初期化し、CURLOPT_URLでアクセス先のURLを、CURLOPT_PROXYで経由するプロキシサーバーのURLを設定します。そして、中心となるCURLOPT_PROXY_PINNEDPUBLICKEYオプションに、前述の公開鍵ファイルパスを設定することで、プロキシとの通信開始前に鍵の検証が自動的に行われます。curl_exec()で実際にリクエストが実行され、成功した場合は取得したコンテンツを文字列で返し、失敗した場合はエラー情報を出力しfalseを返します。最終的にcurl_close()でCURLセッションを閉じ、リソースを解放します。

このサンプルコードを実際に実行するには、動作しているプロキシサーバーと、そのプロキシサーバーの実際の公開鍵ファイル(PEM形式)を$public_key_file_pathに指定されたパスに配置する必要があります。ファイルが見つからない場合は、エラーメッセージが表示されますのでご注意ください。

CURLOPT_PROXY_PINNEDPUBLICKEYは、プロキシサーバーの安全性を高め、中間者攻撃を防ぐための重要なセキュリティオプションです。設定する公開鍵ファイルは、利用するプロキシサーバー本来のPEM形式公開鍵を指定してください。ファイルが存在しない、または鍵が一致しない場合、通信エラーや検証失敗が発生しますので注意が必要です。このオプションはプロキシサーバーの検証に特化しており、アクセス先のサーバー自体の証明書検証とは異なる点にご注意ください。本番環境では、セキュリティリスクを避けるため、SSL検証を無効にする設定は絶対に避けてください。CURLの初期化や実行には失敗の可能性があるため、サンプルコードのように必ずエラーチェックを行い、エラーメッセージを確認する習慣をつけましょう。

PHP cURLでプロキシとSSL証明書検証を行う

1<?php
2
3/**
4 * プロキシ経由でHTTPSリクエストを送信し、SSL証明書検証とプロキシ公開鍵PINNINGを行う関数。
5 *
6 * この関数は、CURLOPT_SSL_VERIFYPEER を使用して接続先サーバーのSSL証明書検証を有効にし、
7 * CURLOPT_PROXY_PINNEDPUBLICKEY を使用してプロキシサーバーの公開鍵PINNINGを設定します。
8 *
9 * 公開鍵PINNINGは、中間者攻撃 (Man-in-the-Middle) を防ぐセキュリティ機能であり、
10 * 指定された公開鍵ハッシュを持つプロキシサーバーのみを信頼するように強制します。
11 *
12 * @param string $url 取得するHTTPSリソースのURL (例: 'https://www.example.com')
13 * @param string $proxy プロキシサーバーのアドレスとポート (例: 'http://myproxy.com:8080')
14 * @param string $proxyPinnedPublicKey プロキシサーバーの公開鍵ハッシュ文字列。
15 *                                     形式は "sha256//<Base64エンコードされたSHA256ハッシュ>" など。
16 *                                     例: 'sha256//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=' (ダミー値)
17 * @return string|false リクエストの結果として得られた文字列、または失敗した場合は false
18 */
19function fetchDataWithProxyAndPinning(string $url, string $proxy, string $proxyPinnedPublicKey)
20{
21    // cURLセッションを初期化します。
22    $ch = curl_init();
23
24    if ($ch === false) {
25        // cURLの初期化に失敗した場合、エラーログに出力し、falseを返します。
26        error_log('cURLセッションの初期化に失敗しました。');
27        return false;
28    }
29
30    // cURLオプションを設定します。
31    // 接続先URLを設定します。
32    curl_setopt($ch, CURLOPT_URL, $url);
33    // 使用するプロキシサーバーを設定します。
34    curl_setopt($ch, CURLOPT_PROXY, $proxy);
35    // cURL_exec() の戻り値を文字列として受け取るように設定します (true = 文字列、false = 直接出力)。
36    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
37    // レスポンスのHTTPヘッダー部分を結果に含めないように設定します。
38    curl_setopt($ch, CURLOPT_HEADER, false);
39
40    // 【キーワード関連】CURLOPT_SSL_VERIFYPEER: 接続先サーバーのSSL証明書を検証するかどうか。
41    // trueに設定することで、サーバーの証明書が本物であるかを検証し、セキュリティを高めます。
42    // 中間者攻撃を防ぐために、この設定を有効にすることが強く推奨されます。
43    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
44
45    // CURLOPT_SSL_VERIFYHOST: 接続先サーバーのホスト名がSSL証明書のホスト名と一致するかどうかを検証します。
46    // 値2は、コモンネーム(CN)とサブジェクト代替名(SAN)の両方をチェックします。
47    // セキュリティのために、この設定も有効にすることが推奨されます。
48    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
49
50    // CURLOPT_PROXY_PINNEDPUBLICKEY: プロキシサーバーの公開鍵PINNINGを設定します。
51    // このオプションは、指定された公開鍵ハッシュを持つプロキシサーバーのみを信頼するように強制します。
52    // 値は "sha256//<Base64エンコードされたSHA256ハッシュ>" の形式で指定します。
53    // 実際の利用では、使用するプロキシサーバーの公開鍵を正しく取得して設定する必要があります。
54    // 間違ったハッシュ値を設定すると、プロキシへの接続が失敗します。
55    curl_setopt($ch, CURLOPT_PROXY_PINNEDPUBLICKEY, $proxyPinnedPublicKey);
56
57    // 設定したオプションでリクエストを実行し、結果を取得します。
58    $response = curl_exec($ch);
59
60    // cURLの実行中にエラーが発生したかどうかをチェックします。
61    if (curl_errno($ch)) {
62        // エラーが発生した場合、エラーメッセージを取得し、ログに出力します。
63        $error_msg = curl_error($ch);
64        error_log("cURLエラーが発生しました: " . $error_msg);
65        $response = false; // エラー時にはfalseを返します。
66    }
67
68    // cURLセッションを終了し、リソースを解放します。
69    curl_close($ch);
70
71    return $response;
72}
73
74// --- サンプル使用例(このままでは動作しません。実際のプロキシと公開鍵が必要です。) ---
75// $targetUrl = 'https://www.example.com';
76// $proxyServer = 'http://your_proxy_server.com:8080'; // あなたのプロキシサーバーのアドレスに置き換えてください
77// // 実際のプロキシサーバーの証明書から抽出した、正しい公開鍵ハッシュ (Base64エンコードされたSHA256ハッシュ) を使用してください。
78// // この値はダミーであり、そのままでは認証に失敗します。
79// $dummyPinnedPublicKey = 'sha256//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=';
80
81// $data = fetchDataWithProxyAndPinning($targetUrl, $proxyServer, $dummyPinnedPublicKey);
82
83// if ($data !== false) {
84//     echo "データ取得に成功しました (最初の100文字):\n";
85//     echo substr($data, 0, 100) . "...\n";
86// } else {
87//     echo "データ取得に失敗しました。\n";
88// }
89

PHPのCURLOPT_PROXY_PINNEDPUBLICKEYは、cURLライブラリを使用してHTTPリクエストを送信する際に、プロキシサーバーの公開鍵を検証するための重要なセキュリティオプションです。この定数自体はint型の値を持つ内部識別子であり、引数はありません。その主な役割は、プロキシ経由での通信時に、悪意のある中間者(Man-in-the-Middle)攻撃から通信を保護することにあります。このオプションを設定することで、cURLは指定された公開鍵ハッシュを持つプロキシサーバーのみを信頼して接続を確立します。

提供されたサンプルコードでは、fetchDataWithProxyAndPinning関数内でこのオプションが利用されています。この関数は、指定されたURLへプロキシ経由でHTTPSリクエストを送信する際に、接続先のSSL証明書検証とプロキシサーバーの公開鍵PINNINGを同時に行います。CURLOPT_PROXY_PINNEDPUBLICKEYには、プロキシサーバーの公開鍵ハッシュをsha256//<Base64エンコードされたSHA256ハッシュ>のような特定の形式で文字列として設定します。この関数は、リクエストが成功すれば取得したデータを文字列として返し、失敗した場合はfalseを返します。

また、サンプルコードではCURLOPT_SSL_VERIFYPEERtrueに設定されており、これは接続先のHTTPSサーバーのSSL証明書が本物であるかどうかの検証を有効にするものです。これらの設定を組み合わせることで、プロキシサーバーと最終的な接続先の両方において、より強固なセキュリティを確保し、安全なデータ通信を実現します。誤った公開鍵ハッシュを設定すると、プロキシへの接続が拒否されるため、正確な情報の設定が非常に重要です。

このコードは、プロキシ経由のHTTPS通信でセキュリティを強化するための設定を含んでいます。CURLOPT_PROXY_PINNEDPUBLICKEYは、指定した公開鍵ハッシュを持つプロキシサーバーのみを信頼する重要な設定です。初心者の方は、この公開鍵ハッシュがサンプルコードのようなダミー値ではなく、実際に利用するプロキシサーバーから正確に取得した値である必要がある点に特に注意してください。値が間違っている場合、セキュリティ検証に失敗し、プロキシへの接続ができません。また、CURLOPT_SSL_VERIFYPEERCURLOPT_SSL_VERIFYHOSTも、接続先サーバーのSSL証明書を検証し、中間者攻撃を防ぐために不可欠な設定です。これらの設定は、本番環境での安全な通信のために常に有効にすることが強く推奨されます。

関連コンテンツ

関連IT用語

関連プログラミング言語