Edited at

PHP-cURLを使ったSSLクライアント認証手順

More than 1 year has passed since last update.

以前PHPにて外部API連携時にSSlクライアント認証させたことがありました。

早々何度も組むことが無いかもしれませんが備忘録として公開。

PHPソケット通信やfile_get_contentsでも可能みたいですが、PHP-curlでSSLクライアント認証を説明。


SSLクライアント認証ロジック

オプションCURLOPT_SSLCERTで、SSL認証に必要なpemファイルを指定。


Connect.php

function execute() 

{
$url = "https://transaction.xxx.xxx/";
$request = 'xxxxxx' . "\r\n";
$request = mb_convert_encoding($request, 'JIS', 'UTF-8');

$length = strlen($request);
$header = array(
"Content-type: text/plain; charset=iso-2022-jp",
"Content-Length: {$length}");

$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $request);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSLCERT, './ssl/ssl.pem');
curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);
$result = curl_exec($curl);
echo $result;
curl_close($curl);
}


PHP公式サイトにも記載されていますが、CURLOPT_SSLCERTの説明欄にはPEM フォーマットの証明書を含むファイルが必要と記載されているので、pem拡張子のファイルを作成。


pemファイル変換

以前参画していた現場では、pemファイルの元となるp12拡張子ファイルが配布されていたので、p12拡張子から証明書と鍵情報を抽出してpemファイルに変換。

// pkcs12 形式の証明書を読込 (source.p12)

$pass = '証明書作成時のパスフレーズ';
$pkcs12File = 'source.p12';
$pkcs12 = file_get_contents($pkcs12File);
$certs = array();
openssl_pkcs12_read($pkcs12, $certs, $pass);

// PEM 形式で保存 (output.pem)
$pemFile = 'output.pem';
file_put_contents($pemFile, $certs['cert'] . $cert['pkey']);

証明書と鍵を同一ファイル内に記載したもので接続しました。

証明書と鍵を別々のpemに分割して接続することも可能なようですが、私には出来なかったので同一pem内での方式にしています。CURLOPT_CAPATHはサーバー証明証を設定するオプションなので、クライアント認証時にはCURLOPT_SSLCERTを利用しましょう。