以前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を利用しましょう。