【PHP8.x】openssl_pkcs7_encrypt関数の使い方

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

作成日: 更新日:

基本的な使い方

openssl_pkcs7_encrypt関数は、データをPKCS7形式で暗号化し、必要に応じてデジタル署名を付与する関数です。この関数は、データの機密性(内容を秘密にすること)と完全性(改ざんされていないこと)を同時に確保するためのセキュアなデータ交換プロトコルであるPKCS7の形式に従って処理を行います。

具体的には、入力されたデータを、指定された受信者の公開鍵証明書を用いて暗号化します。これにより、暗号化されたデータは、対応する秘密鍵を持つ正規の受信者のみが復号し、内容を安全に閲覧できるようになります。不正なアクセスからデータを保護するために重要な機能です。

さらに、オプションとして送信者の秘密鍵と証明書を指定することで、暗号化されたデータにデジタル署名を付与することも可能です。このデジタル署名は、データが確かに指定された送信者によって作成されたものであり、転送中に一切改ざんされていないことを保証します。

この関数は、主にセキュアな電子メール通信(S/MIMEなど)や、信頼性の高いデータのやり取りが必要なシステムで利用されます。関数を使用する際には、暗号化したいデータ、受信者の公開鍵証明書、出力ファイルパスなどを引数として指定します。処理が成功した場合はtrueを、失敗した場合はfalseを返します。PHPのOpenSSL拡張が有効になっている環境で利用可能です。

構文(syntax)

1<?php
2$result = openssl_pkcs7_encrypt(
3    'path/to/input.txt',                               // 入力ファイルのパス (string)
4    'path/to/output.p7m',                              // 出力ファイルのパス (string)
5    'file:///path/to/recipient_certificate.pem',       // 受信者の証明書 (mixed: ファイルパス、文字列、リソース)
6    ['file:///path/to/sender_private_key.pem', 'your_private_key_password'], // 送信者の秘密鍵とパスフレーズ (mixed: 配列、ファイルパス、文字列、リソース)
7    [],                                                // オプション: ヘッダ (array)
8    0,                                                 // オプション: フラグ (int)
9    OPENSSL_CIPHER_AES256_CBC                          // オプション: 暗号化アルゴリズム (int)
10);
11?>

引数(parameters)

string $input_filename, string $output_filename, OpenSSLCertificate|array|string $certificate, array|string $headers, int $flags = 0, int $cipher_algo = OPENSSL_CIPHER_AES128_CBC

  • string $input_filename: 暗号化する元となるファイル名を指定します。
  • string $output_filename: 暗号化されたデータを保存するファイル名を指定します。
  • OpenSSLCertificate|array|string $certificate: 暗号化に使用する公開鍵証明書を指定します。OpenSSLCertificateオブジェクト、証明書のファイルパス、または証明書の内容を表す文字列で指定できます。
  • array|string $headers: PKCS#7メッセージのヘッダー情報を指定します。配列または文字列で指定できます。
  • int $flags = 0: 暗号化の動作を制御するフラグを指定します。デフォルトは0です。
  • int $cipher_algo = OPENSSL_CIPHER_AES128_CBC: 暗号化に使用するアルゴリズムを指定します。デフォルトはAES128_CBCです。

戻り値(return)

bool

openssl_pkcs7_encrypt 関数は、PKCS#7 形式でデータを暗号化することに成功したかどうかを示す真偽値 (bool) を返します。成功した場合は true、失敗した場合は false を返します。

サンプルコード

PHP openssl_pkcs7_encryptでデータを暗号化する

1<?php
2
3/**
4 * openssl_pkcs7_encrypt を使用してデータを暗号化するサンプル
5 *
6 * この関数は、PKCS7 (S/MIME) 形式でデータを暗号化する一連の流れを示します。
7 * 暗号化には公開鍵証明書が必要なため、このサンプル内では
8 * テスト目的で自己署名証明書を動的に生成しています。
9 */
10function encryptDataWithPkcs7(): void
11{
12    // --- 1. 準備 ---
13
14    // 暗号化する平文データ
15    $plainData = 'これは暗号化される秘密のメッセージです。';
16
17    // S/MIMEメッセージに含めるヘッダ情報
18    $headers = [
19        'To' => 'recipient@example.com',
20        'From' => 'sender@example.com',
21        'Subject' => '秘密のメッセージ (暗号化済)',
22    ];
23
24    // 一時的に使用するファイルパスを準備
25    $inputFile = tempnam(sys_get_temp_dir(), 'p7_in_');
26    $outputFile = tempnam(sys_get_temp_dir(), 'p7_out_');
27
28    // 平文データを入力ファイルに書き込む
29    file_put_contents($inputFile, $plainData);
30
31
32    // --- 2. 暗号化に使用する証明書の生成 (テスト用) ---
33    // 通常、証明書は認証局(CA)から取得するか、事前に準備しておきます。
34    // このサンプルでは、テストのために自己署名証明書を動的に生成します。
35
36    // 秘密鍵を生成
37    $privateKey = openssl_pkey_new([
38        'private_key_bits' => 2048,
39        'private_key_type' => OPENSSL_KEYTYPE_RSA,
40    ]);
41    if ($privateKey === false) {
42        echo 'エラー: 秘密鍵の生成に失敗しました。' . PHP_EOL;
43        return;
44    }
45
46    // 証明書署名要求(CSR)を生成
47    $csr = openssl_csr_new(['commonName' => 'example.com'], $privateKey);
48    if ($csr === false) {
49        echo 'エラー: CSRの生成に失敗しました。' . PHP_EOL;
50        return;
51    }
52
53    // CSRに自己署名して証明書(x509)を生成
54    $certificate = openssl_csr_sign($csr, null, $privateKey, 365);
55    if ($certificate === false) {
56        echo 'エラー: 自己署名証明書の生成に失敗しました。' . PHP_EOL;
57        return;
58    }
59
60
61    // --- 3. openssl_pkcs7_encrypt を使用して暗号化を実行 ---
62
63    echo '暗号化処理を実行します...' . PHP_EOL;
64    $isSuccess = openssl_pkcs7_encrypt(
65        $inputFile,             // (string) 暗号化するデータを含むファイル
66        $outputFile,            // (string) 暗号化されたデータの出力先ファイル
67        $certificate,           // (OpenSSLCertificate) 暗号化に使用する公開鍵証明書
68        $headers,               // (array) S/MIMEヘッダ
69        0,                      // (int) フラグ (オプション)
70        OPENSSL_CIPHER_AES256_CBC // (int) 暗号化アルゴリズム (オプション)
71    );
72
73
74    // --- 4. 結果の確認と後処理 ---
75
76    if ($isSuccess) {
77        echo '暗号化に成功しました。' . PHP_EOL . PHP_EOL;
78        echo '--- 暗号化されたデータ (S/MIME形式) ---' . PHP_EOL;
79        echo file_get_contents($outputFile);
80        echo PHP_EOL;
81        echo '----------------------------------------' . PHP_EOL;
82    } else {
83        echo '暗号化に失敗しました。' . PHP_EOL;
84        // OpenSSLのエラーキューから詳細なエラーメッセージを取得
85        while ($msg = openssl_error_string()) {
86            echo $msg . PHP_EOL;
87        }
88    }
89
90    // 作成した一時ファイルを削除
91    unlink($inputFile);
92    unlink($outputFile);
93}
94
95// サンプル関数を実行
96encryptDataWithPkcs7();

openssl_pkcs7_encrypt関数は、公開鍵証明書を使って、指定されたファイルをPKCS7(S/MIME)形式で暗号化するためのものです。この形式は主に安全な電子メールの送受信などで利用されます。

サンプルコードでは、まず暗号化したい平文データとメッセージヘッダを準備し、平文を一時ファイルに書き込みます。暗号化には受信者の公開鍵証明書が不可欠ですが、この例ではテスト目的で自己署名証明書をその場で生成して使用しています。

関数の呼び出し部分が実際の暗号化処理です。第1引数に平文データが入った入力ファイルパス、第2引数に暗号化データを出力するファイルパスを指定します。第3引数には暗号化に用いる公開鍵証明書を、第4引数にはS/MIMEメッセージに含めるヘッダ情報を配列で渡します。オプションの第6引数で、OPENSSL_CIPHER_AES256_CBCのような具体的な暗号化アルゴリズムを指定することも可能です。

この関数の戻り値はbool型で、処理が成功すればtrueを、失敗すればfalseを返します。成功した場合、第2引数で指定した出力ファイルには、ヘッダ情報と共に暗号化されたデータがS/MIME形式で書き込まれます。

この関数は文字列ではなくファイルを使って暗号化処理を行うため、一時ファイルの作成と処理後の確実な削除が必要です。サンプル内の自己署名証明書の生成はテスト目的です。実際のシステムでは、暗号化してデータを渡したい相手の公開鍵証明書を、信頼できる認証局から入手して使用してください。これによって、対応する秘密鍵を持つ受信者だけが内容を復号できるようになります。処理が失敗した場合は、openssl_error_string() を呼び出すことで詳細なエラー原因を調査でき、デバッグに役立ちます。

関連コンテンツ

【PHP8.x】openssl_pkcs7_encrypt関数の使い方 | いっしー@Webエンジニア