🐘

自己証明書の環境でfile_get_contents()が動かない場合の解決法

2022/10/13に公開約1,900字

自分は現在、WordPressでHPを作る際に、Local(旧名: Local By FlyWheel)を使用していますが、
ローカル環境がSSL化されていないことに気がつきました
https://localwp.com/

調べたところ、MacOS BigSur以降は自動で証明書を信頼することができないようで、手動でキーチェーンアクセスから証明書を信頼する必要があるようです
自分は↓のリンクの方法で、ローカル環境を自己証明書でSSL化することができました
https://localwp.com/help-docs/ssl/managing-local-sites-ssl-certificate-in-macos/

しかし、今度はfile_get_contents()が下記のエラーで動作しなくなったため、今回はその解決法をメモしておきます

 Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:XXXXXX:SSL routines:tls_process_server_certificate:certificate verify failed in XXXXXX

解決法

file_get_contents()の第3引数のコンテキストオプションで、
SSLコンテキストオプションのallow_self_signedにtrueを設定するだけです

$context = stream_context_create(
  'ssl' => [
    'allow_self_signed' => true,
  ],
);

file_get_contents('ファイルパス', false, $context);

https://www.php.net/manual/ja/function.file-get-contents.php

他の記事ではverify_peerverify_peer_nameをfalseにするように紹介している内容をよく見かけました。
しかし、それだと自己証明書以外のSSL証明書の検証まで外してしまうため、自己証明の証明書を許可するallow_self_signedをtrueにするだけで良いと考えています

https://www.php.net/manual/ja/context.ssl.php

原因

PHP5.6からOpenSSL関連の仕様変更があったようで、ストリームのピア検証がデフォルトで有効になったのが原因のようです

暗号化されたすべてのクライアントストリームで、ピア検証がデフォルトで有効になりました。 デフォルトでは、OpenSSL のデフォルト CA バンドルを使ってピア証明書を検証します。 たいていの場合は、正しい SSL 証明書を持つサーバーと通信するならこれを変更する必要はありません。 OpenSSL が、よく知られた CA バンドルを使うように設定されているからです。
一般的にはおすすめできませんが、 コンテキストオプション verify_peer を false にしてリクエストでのピア証明書の検証を無効化することもできます。 また同じく、ピア名の検証も、コンテキストオプション verify_peer_name を false にすれば無効化できます。

https://www.php.net/manual/ja/migration56.openssl.php

おまけ

自分はBasic認証に対応するために、下記のように認証オプションも入れています

$context = stream_context_create(
  'ssl' => [
    'allow_self_signed' => true,
  ],
  'http' => [
    'method' => 'GET',
    'header' => 'Authorization: Basic ' . base64_encode($_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW'])
  ],
);

file_get_contents('ファイルパス', false, $context);

https://zenn.dev/yogarasu/articles/40d70847a615b9

Discussion

ログインするとコメントできます