• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:fsockopenを使った証明書付きのSSL通信)

fsockopenを使った証明書付きのSSL通信

このQ&Aのポイント
  • fsockopenには6つ目のパラメータを渡すことができません
  • 証明書を使用しない場合にはSSL通信ができません
  • 解決方法を探していますが、まだ見つかっていません

質問者が選んだベストアンサー

  • ベストアンサー
  • NARH
  • ベストアンサー率82% (88/107)
回答No.2

幾つかの pem ファイルを指定していることから、SSL クライアント認証が必要なサーバにアクセスしてコンテンツを得たいということですよね? ソケットを開いて openssl関数を駆使して自前で頑張るのもアリですが、参照URLのとおり面倒なネゴシエーションをしなくてはなりません。 頑張って実装してください。。 って面倒ですよね。もし cURL extension が利用できるのであれば以下のソースが参考になるかもしれません。手元にすぐにSSLクライアント認証が試せる環境がなかったので動作は未検証になります。 <?php if( function_exists( 'curl_init' ) === FALSE ) { die( 'cURL 使えないッス!' ); } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'aaa.bbb.ne.jp'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // コンテンツはテキスト文字列 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_CAPATH, 'client.pem のあるディレクトリを指定'); curl_setopt($ch, CURLOPT_CAINFO, 'ca.pem をフルパス指定'); curl_setopt($ch, CURLOPT_SSLCERT, 'client.pem'); curl_setopt($ch, CURLOPT_SSLCERTPASSWD, 'client.pem のパスワードを指定'); // CURLOPT_RETURNTRANSFER を 1 にしているのでresponse body を変数に格納 $result = curl_exec($ch); curl_close($ch); echo $result .PHP_EOL exit;

参考URL:
http://alk.dip.jp/apache2-default/sv290.html
seiroku55
質問者

お礼

ありがとうございます。 ご丁寧にサンプルまで。。。(泣) curlが使えない状態だったので、PHPのリコンパイルして使えるようになったのですが、 実行しても、実行中のまま変化なしでした。 どうもpfxから変換したpemが怪しいような気がしてきました。 中身が理解できてなくて、コピペだからうまくいかないんですよね。 参考URLなど勉強してもうちょっとがんばってみます。 ありがとうございます。

その他の回答 (5)

  • NARH
  • ベストアンサー率82% (88/107)
回答No.6

hogehoge78 さんの Zend Framework 簡単でいいですね。 Zend Framework はコンポーネントを単体でライブラリのように使えると聞いたことがあります。#使ったことがないのでわかりません。 導入するのに抵抗がないのであれば HTTP ヘッダをパースしてクッキーにセットしてなど雑多な処理から開放されそうです。 質問者の方の補足の質問ですが、人間がブラウザを利用して操作する事をトレースするわけですから、 curl_init() をリクエスト回数分コールすることになりそうです。 設定したオプションを再利用したいのであれば curl_setopt_array() や curl_copy_handle() があるようですので関数やオブジェクトのメソッドでラッピングして使うと便利そうですね。 先のZend_Http_Clientを使う案も素敵だと思います。 #Webアプリケーションなんでしょうか?だとしたら本来各ブラウザで分散される処理を一手に引き受けるのですからアクセス数によってはCPUぶん回しになりそうですね。接続先はSSLアクセラレータが使えるかもしれませんが、クライアントの振舞いをする側はそうはいきませんし。

seiroku55
質問者

お礼

>人間がブラウザを利用して操作する事をトレースするわけですから、 そういうことなんですね。 やっとイメージできました。 一応curlを何度かたたくことで実現できました!! これからZendも試してみようと思います。 未知の世界だったのですが、少し理解することができました。 ありがとうございました!!

回答No.5

よこからですみませんが、 HTTPの通信は、一度のリクエストとレスポンスの組ですので、最後にcurl_close関数を叩いたら、 次回もう一度、curl_initをし直す必要があります。 また、curlだけに限らない話ですが、セッションを引き継ぐリクエストを送るときに自前でコードを記述するのは結構手間がかかるので、ZendFrameworkの「Zend_Http_Client」をライブラリとして使ってみてはいかがでしょう。 NARHさんの書かれたスクリプトを参考にして、Zend_Http_Clientを使った記述は、 <?php /* Zend Framework ダウンロードはここ http://framework.zend.com/download/latest Zend_Http_Clientのマニュアルはここ http://framework.zend.com/manual/ja/zend.http.client.adapters.html */ require_once 'Zend/Http/Client.php'; $uri = 'https://example.com'; $config = array( 'adapter' => 'Zend_Http_Client_Adapter_Curl', 'curloptions' => array( CURLOPT_RETURNTRANSFER => 1, CURLOPT_SSL_VERIFYHOST => 1, CURLOPT_SSL_VERIFYPEER => 1, CURLOPT_CAPATH => 'path', CURLOPT_CAINFO => 'path/to/ca.pem', CURLOPT_SSLCERT => 'path/to/client.pem', CURLOPT_SSLCERTPASSWD => 'password', ), ); $client = new Zend_Http_Client($uri, $config); $client->setCookieJar();//セッションを保持できるようにします。 $client->setParameterPost('name', 'value'); //POST値を入力します。 $response = $client->request('POST'); if($response->getStatus() == 200){ $client->setUri('http://example.com/next/page'); $response = $client->request('GET'); } ?> このようになります。 アダプタとして、curlを使いますので(別のモジュールを選択することも可能)、内部的には、NARHさんのやっていることと同じです。 ソレとは別に、Cookieで取得したセッション用のIDなどを取り持って次の遷移に持込してくれるルーチンが仕込まれています。 ご参考まで。

seiroku55
質問者

お礼

Zendは使ったことがありませんでした。 とてもわかりやすいサンプルをありがとうございました。 早速試してみます。

  • NARH
  • ベストアンサー率82% (88/107)
回答No.4

実は、先ほどのサンプルではポート指定を忘れてました。(テヘッ!) curl_setopt($ch, CURLOPT_URL, 'https://aaa.bbb.ne.jp'); でもいけると思います。 #すみません。相変わらず未検証です。 でも pem が上手くいっていなかったらダメなんですが、タイムアウトの指定はできたので、PHP のcURLのマニュアルも参考にしてみてくださいね。 #Web上にあんまりビンゴな資料ってありそうでないですね。

seiroku55
質問者

お礼

再びありがとうございます! なんと証明書の件はクリアできました。 pemの件はOKだったようです。 また別の問題が・・・ アクセス先のサイトは、SSL証明書を通過したあと、更にログインの必要があり、 セッションを持ちまわっているようなのです。 その後、必要なパラメータをPOSTして情報を引き出します。 このような場合は、いったんログインページにcurl_initし、 その後検索フォームのページで再びcurl_initするようなイメージでいいのでしょうか。 あつかましくて申し訳ありませんが、もしお分かりのようでしたら ご教授いただけると助かります。 よろしくお願いいたします。

回答No.3

〉No.2 勉強になりました。 ネットワークはきちんと勉強しなくては行けませんね。 質問者さんにも、外した回答してすみませんでした。 とりあえず stream_context_createで作ったコンテキストつきで通信する場合は、stream_socket_clientが使えます。 http://jp.php.net/stream_socket_client

seiroku55
質問者

お礼

ありがとうございました。 ネットワーク難しいです。 勉強になります。

回答No.1

PHPが、OpenSSLのサポートが有効な状態でインストールされていますか? その場合であれば、「ssl://」といったスキームを記述してやれば、自動的に暗号化して通信を行うので そのようなエラーが出てくることは無いと思います。(プロキシかましてたりすると一手間かける必要がありますが・・・) phpinfo(); あたりで、OpenSSLのサポートが有効になっているか確認してみてはいかがでしょう。

関連するQ&A