Webエンジニア向けプログラミング解説動画をYouTubeで配信中!
▶ チャンネル登録はこちら

【PHP8.x】openssl_public_encrypt()関数の使い方

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

作成日: 更新日:

基本的な使い方

openssl_public_encrypt関数は、OpenSSL拡張機能の一部として、公開鍵暗号方式を使用してデータを暗号化する関数です。この関数は、与えられた平文のデータと公開鍵を受け取り、そのデータを暗号化して、対応する秘密鍵でのみ復号できる形式に変換します。公開鍵暗号方式は、データを暗号化するための公開鍵と、それを復号するための秘密鍵という対になる鍵を用いる方式であり、これにより高いセキュリティを実現します。

具体的には、インターネット上での通信において、共通鍵(対称鍵暗号方式で使用される鍵)を安全に交換する際や、少量の機密情報を保護したい場合などに利用されます。例えば、ウェブサイトとの安全な通信(SSL/TLS)の初期段階で、クライアントが生成した共通鍵をサーバーの公開鍵で暗号化し、安全にサーバーへ送るといった用途が挙げられます。

この関数を使用することで、第三者によるデータの盗聴や改ざんのリスクを低減し、情報の機密性を確保することが可能になります。関数は、暗号化したい元のデータ、暗号化されたデータが格納される変数を参照渡しで指定し、さらに暗号化に用いる公開鍵を引数として受け取ります。処理が成功した場合は true を、失敗した場合は false を返します。データのセキュリティを確保する上で非常に重要な役割を果たす関数の一つです。

構文(syntax)

1<?php
2$dataToEncrypt = "秘密の情報です。";
3$encryptedData = '';
4$publicKeyPem = '-----BEGIN PUBLIC KEY-----ここに実際の公開鍵の内容を貼り付けます-----END PUBLIC KEY-----';
5
6$success = openssl_public_encrypt($dataToEncrypt, $encryptedData, $publicKeyPem, OPENSSL_PKCS1_PADDING);
7?>

引数(parameters)

string $data, string &$encrypted_data, mixed $public_key, int $padding = OPENSSL_PKCS1_PADDING

  • string $data: 暗号化する元のデータ
  • string &$encrypted_data: 暗号化された結果を格納する変数(参照渡し)
  • mixed $public_key: 公開鍵(PEM形式の文字列、またはopenssl_pkey_get_public()で取得したリソース)
  • int $padding = OPENSSL_PKCS1_PADDING: パディング方式を指定する整数

戻り値(return)

bool

openssl_public_encrypt関数は、公開鍵暗号化の実行に成功したかどうかを示す真偽値 (bool) を返します。暗号化が成功した場合は true、失敗した場合は false を返します。

サンプルコード

PHP openssl_public_encryptで公開鍵暗号化する

1<?php
2
3// エラー報告を有効にする
4error_reporting(E_ALL);
5ini_set('display_errors', '1');
6
7/**
8 * openssl_public_encrypt 関数を使用してデータを公開鍵で暗号化し、
9 * openssl_private_decrypt 関数で秘密鍵を使って復号化するサンプルコードです。
10 *
11 * このスクリプトは、RSA鍵ペアを生成し、その鍵ペアを使って暗号化と復号化を行います。
12 * システムエンジニアを目指す初心者にも理解しやすいように、各ステップにコメントを付与しています。
13 */
14
15echo "--- 公開鍵暗号化/秘密鍵復号化のデモンストレーション ---" . PHP_EOL . PHP_EOL;
16
17// 1. RSA鍵ペアの生成
18// openssl_pkey_new() を使用して、新しいRSA鍵ペアを生成します。
19// 鍵のビット長は2048ビット、タイプはRSAを指定しています。
20$privateKeyResource = openssl_pkey_new([
21    "private_key_bits" => 2048,
22    "private_key_type" => OPENSSL_KEYTYPE_RSA,
23]);
24
25if (!$privateKeyResource) {
26    die("エラー: 秘密鍵の生成に失敗しました。" . PHP_EOL . implode(PHP_EOL, openssl_error_string()));
27}
28
29// 生成した秘密鍵をPEM形式の文字列として取得します。
30// この秘密鍵は安全に保管する必要があります。
31openssl_pkey_export($privateKeyResource, $privateKeyPem);
32// echo "生成された秘密鍵 (PEM形式):" . PHP_EOL . $privateKeyPem . PHP_EOL;
33
34// 秘密鍵リソースから公開鍵の詳細情報を取得します。
35$publicKeyDetails = openssl_pkey_get_details($privateKeyResource);
36// 公開鍵をPEM形式の文字列として取得します。
37// この公開鍵は暗号化のために安全でないチャネルで共有できます。
38$publicKeyPem = $publicKeyDetails['key'];
39// echo "生成された公開鍵 (PEM形式):" . PHP_EOL . $publicKeyPem . PHP_EOL;
40
41// 2. 暗号化に使用する公開鍵リソースの準備
42// openssl_get_publickey() を使用して、PEM形式の公開鍵文字列からリソースを作成します。
43$publicKeyForEncryption = openssl_get_publickey($publicKeyPem);
44if (!$publicKeyForEncryption) {
45    die("エラー: 暗号化のための公開鍵リソースの読み込みに失敗しました。" . PHP_EOL . implode(PHP_EOL, openssl_error_string()));
46}
47
48// 3. 暗号化するデータの準備
49$originalData = "Hello, System Engineer Beginner! This is a secret message.";
50echo "元データ: " . $originalData . PHP_EOL;
51
52$encryptedData = ''; // 暗号化されたデータが格納される変数
53
54// 4. openssl_public_encrypt() 関数によるデータの暗号化
55// 元データと公開鍵リソースを使用してデータを暗号化します。
56// 暗号化されたデータは `$encryptedData` に参照渡しで格納されます。
57// パディングには OPENSSL_PKCS1_PADDING (デフォルト) を使用します。
58$encryptionSuccess = openssl_public_encrypt($originalData, $encryptedData, $publicKeyForEncryption);
59
60if ($encryptionSuccess) {
61    // 暗号化されたデータはバイナリ形式のため、表示や保存のためにBase64エンコードするのが一般的です。
62    $base64EncryptedData = base64_encode($encryptedData);
63    echo "暗号化されたデータ (Base64エンコード): " . $base64EncryptedData . PHP_EOL;
64} else {
65    echo "エラー: 暗号化に失敗しました。" . PHP_EOL;
66    // openssl_error_string() を使用してOpenSSLのエラーメッセージを取得します。
67    while ($msg = openssl_error_string()) {
68        echo $msg . PHP_EOL;
69    }
70    // エラーが発生した場合は、後続の復号化処理を行わない
71    exit(1);
72}
73
74// 5. 復号化に使用する秘密鍵リソースの準備
75// openssl_get_privatekey() を使用して、PEM形式の秘密鍵文字列からリソースを作成します。
76// このリソースは、暗号化されたデータを復号化するために使用されます。
77$privateKeyForDecryption = openssl_get_privatekey($privateKeyPem);
78if (!$privateKeyForDecryption) {
79    die("エラー: 復号化のための秘密鍵リソースの読み込みに失敗しました。" . PHP_EOL . implode(PHP_EOL, openssl_error_string()));
80}
81
82$decryptedData = ''; // 復号化されたデータが格納される変数
83
84// 6. openssl_private_decrypt() 関数によるデータの復号化
85// 暗号化されたデータ (Base64デコードしたもの) と秘密鍵リソースを使用してデータを復号化します。
86// 復号化されたデータは `$decryptedData` に参照渡しで格納されます。
87$decryptionSuccess = openssl_private_decrypt($encryptedData, $decryptedData, $privateKeyForDecryption);
88
89if ($decryptionSuccess) {
90    echo "復号化されたデータ: " . $decryptedData . PHP_EOL;
91    // 元データと復号化されたデータが一致するか確認
92    if ($originalData === $decryptedData) {
93        echo "結果: 復号化に成功し、元データと一致しました。" . PHP_EOL;
94    } else {
95        echo "結果: 復号化に成功しましたが、データが一致しません。" . PHP_EOL;
96    }
97} else {
98    echo "エラー: 復号化に失敗しました。" . PHP_EOL;
99    while ($msg = openssl_error_string()) {
100        echo $msg . PHP_EOL;
101    }
102}
103
104// 7. OpenSSLリソースの解放
105// メモリリークを防ぐため、使用済みのOpenSSLリソースを解放します。
106openssl_free_key($privateKeyResource);      // 最初Pkey_newで生成した秘密鍵リソース
107openssl_free_key($publicKeyForEncryption);  // 公開鍵リソース
108openssl_free_key($privateKeyForDecryption); // 復号化用秘密鍵リソース
109
110echo PHP_EOL . "--- デモンストレーション終了 ---" . PHP_EOL;
111
112?>

PHP 8のopenssl_public_encrypt関数は、指定されたデータを公開鍵で暗号化するために使用されます。これは非対称暗号化の一種で、公開鍵で暗号化されたデータは、対応する秘密鍵でしか復号できないという特徴を持ちます。

このサンプルコードでは、まずopenssl_pkey_new関数を用いてRSA鍵ペア(公開鍵と秘密鍵)を生成します。次に、暗号化したい文字列データと、生成した公開鍵リソースをopenssl_public_encrypt関数の引数に渡して実行します。第1引数$dataには暗号化する元のデータ、第2引数&$encrypted_dataには暗号化結果が参照渡しで格納され、第3引数$public_keyには公開鍵を指定します。戻り値は暗号化の成否を示す真偽値(bool)です。暗号化されたデータはバイナリ形式のため、通常はBase64エンコードして表示や保存が行われます。その後、openssl_private_decrypt関数で対応する秘密鍵を使ってデータを復号化し、元のデータに戻せることを示しています。これにより、データの機密性を保ちながら安全に情報をやり取りすることが可能となります。

openssl_public_encrypt関数で公開鍵暗号化を行う際、秘密鍵の厳重な管理が最も重要です。サンプルコードでは鍵を生成していますが、本番環境では安全な場所から読み込み、絶対に漏洩させないでください。この関数で直接暗号化できるデータのサイズは公開鍵のサイズに制限があるため、大きなデータを扱う場合は共通鍵暗号方式と組み合わせたハイブリッド暗号化を検討してください。パディングには、デフォルトのOPENSSL_PKCS1_PADDINGよりも、より安全性の高いOPENSSL_PKCS1_OAEP_PADDINGの使用を強く推奨します。暗号化されたデータはバイナリ形式なので、表示や保存、ネットワーク転送にはBase64エンコードなどを利用してください。関数の成功は戻り値で確認し、エラー発生時はopenssl_error_string()で詳細な情報を取得することが大切です。また、使用し終わったOpenSSLリソースは忘れずにopenssl_free_key()で解放し、メモリリークを防ぎましょう。

PHP openssl_public_encryptで公開鍵暗号化する

1<?php
2
3/**
4 * PHPのopenssl_public_encrypt関数を使用してデータを公開鍵で暗号化し、
5 * その後、対応する秘密鍵で復号化するサンプルコードです。
6 * システムエンジニアを目指す初心者にも分かりやすく、一連の処理を示します。
7 */
8function encryptAndDecryptDataWithOpenSsl(): void
9{
10    echo "--- OpenSSL 公開鍵暗号化と秘密鍵復号化の例 ---" . PHP_EOL . PHP_EOL;
11
12    // 1. 鍵ペアの生成
13    // openssl_pkey_new() を使用して、RSAタイプの秘密鍵と公開鍵のペアを生成します。
14    // これはテスト目的であり、本番環境では鍵の適切な管理とより安全な設定が必要です。
15    $config = [
16        "private_key_bits" => 2048, // 鍵のビット数 (推奨: 2048ビット以上)
17        "private_key_type" => OPENSSL_KEYTYPE_RSA, // RSA鍵タイプ
18    ];
19    $privateKeyResource = openssl_pkey_new($config);
20
21    if ($privateKeyResource === false) {
22        echo "エラー: 鍵ペアの生成に失敗しました。" . PHP_EOL . openssl_error_string() . PHP_EOL;
23        return;
24    }
25
26    // 生成した秘密鍵をPEM形式の文字列として取得
27    openssl_pkey_export($privateKeyResource, $privateKeyPem);
28
29    // 生成した公開鍵をPEM形式の文字列として取得
30    $publicKeyDetails = openssl_pkey_get_details($privateKeyResource);
31    $publicKeyPem = $publicKeyDetails['key'];
32
33    echo "--- 生成された鍵情報 ---" . PHP_EOL;
34    echo "秘密鍵 (PEM形式):" . PHP_EOL . $privateKeyPem . PHP_EOL;
35    echo "公開鍵 (PEM形式):" . PHP_EOL . $publicKeyPem . PHP_EOL;
36    echo PHP_EOL;
37
38    // 2. 暗号化する元のデータ
39    $originalData = "This is a confidential message that needs to be secured using RSA encryption.";
40    echo "元のデータ: " . $originalData . PHP_EOL;
41    echo PHP_EOL;
42
43    // 3. openssl_public_encrypt() を使って公開鍵でデータを暗号化
44    // 公開鍵のPEM形式文字列から、OpenSSL関数が使用できるリソース形式に変換します。
45    $publicKeyForEncryption = openssl_pkey_get_public($publicKeyPem);
46    $encryptedData = ''; // 暗号化されたデータが格納される変数を初期化
47
48    if ($publicKeyForEncryption === false) {
49        echo "エラー: 公開鍵リソースの読み込みに失敗しました。" . PHP_EOL . openssl_error_string() . PHP_EOL;
50        openssl_free_key($privateKeyResource);
51        return;
52    }
53
54    // openssl_public_encrypt 関数を呼び出してデータを暗号化します。
55    // 第1引数: 暗号化する元の文字列データ
56    // 第2引数: 暗号化されたデータが格納される参照変数 ($encryptedDataに結果が代入される)
57    // 第3引数: 公開鍵のリソース
58    // 第4引数: パディング方式 (OPENSSL_PKCS1_PADDING は最も一般的なRSAパディング方式)
59    $encryptionSuccess = openssl_public_encrypt(
60        $originalData,
61        $encryptedData,
62        $publicKeyForEncryption,
63        OPENSSL_PKCS1_PADDING
64    );
65
66    if ($encryptionSuccess) {
67        echo "データの暗号化に成功しました。" . PHP_EOL;
68        // 暗号化されたデータはバイナリ形式なので、表示や保存のためにBase64エンコードします。
69        echo "暗号化されたデータ (Base64エンコード): " . base64_encode($encryptedData) . PHP_EOL;
70        echo PHP_EOL;
71    } else {
72        echo "エラー: データの暗号化に失敗しました。" . PHP_EOL . openssl_error_string() . PHP_EOL;
73        openssl_free_key($privateKeyResource);
74        openssl_free_key($publicKeyForEncryption);
75        return;
76    }
77
78    // 4. openssl_private_decrypt() を使って秘密鍵でデータを復号化 (動作確認のため)
79    // 秘密鍵のPEM形式文字列から、OpenSSL関数が使用できるリソース形式に変換します。
80    $privateKeyForDecryption = openssl_pkey_get_private($privateKeyPem);
81    $decryptedData = ''; // 復号化されたデータが格納される変数を初期化
82
83    if ($privateKeyForDecryption === false) {
84        echo "エラー: 秘密鍵リソースの読み込みに失敗しました。" . PHP_EOL . openssl_error_string() . PHP_EOL;
85        openssl_free_key($privateKeyResource);
86        openssl_free_key($publicKeyForEncryption);
87        return;
88    }
89
90    // openssl_private_decrypt 関数を呼び出してデータを復号化します。
91    // 暗号化時と同じパディング方式を使用する必要があります。
92    $decryptionSuccess = openssl_private_decrypt(
93        $encryptedData,
94        $decryptedData,
95        $privateKeyForDecryption,
96        OPENSSL_PKCS1_PADDING
97    );
98
99    if ($decryptionSuccess) {
100        echo "データの復号化に成功しました。" . PHP_EOL;
101        echo "復号化されたデータ: " . $decryptedData . PHP_EOL;
102        echo PHP_EOL;
103
104        // 元のデータと復号化されたデータが一致するか確認
105        if ($originalData === $decryptedData) {
106            echo "検証: 元のデータと復号化されたデータは一致します。" . PHP_EOL;
107        } else {
108            echo "検証エラー: 元のデータと復号化されたデータが一致しません。" . PHP_EOL;
109        }
110    } else {
111        echo "エラー: データの復号化に失敗しました。" . PHP_EOL . openssl_error_string() . PHP_EOL;
112    }
113
114    // 使用した鍵リソースを解放します。
115    // PHPはスクリプト終了時に自動的に解放しますが、明示的に行うこともできます。
116    openssl_free_key($privateKeyResource);
117    openssl_free_key($publicKeyForEncryption);
118    openssl_free_key($privateKeyForDecryption);
119
120    echo PHP_EOL . "--- 例の終了 ---" . PHP_EOL;
121}
122
123// サンプル関数の実行
124encryptAndDecryptDataWithOpenSsl();

PHPのopenssl_public_encrypt関数は、指定されたデータを公開鍵で暗号化するために使用されます。この関数で暗号化されたデータは、対応する秘密鍵でのみ復号化可能となり、機密性の高い情報の保護に役立ちます。

引数には、暗号化する元の文字列$data、暗号化結果を格納する参照変数&$encrypted_data、公開鍵のリソース$public_key、およびパディング方式$padding(例: OPENSSL_PKCS1_PADDING)を指定します。関数は、処理の成功時にtrueを、失敗時にfalseを戻り値として返します。

サンプルコードでは、まずopenssl_pkey_newで秘密鍵と公開鍵のペアを生成します。次に、openssl_public_encryptを使って元のデータを生成した公開鍵で暗号化し、結果を$encrypted_dataに格納します。暗号化されたデータはバイナリ形式のため、通常はBase64エンコードして扱われます。さらに、暗号化が正しく行われたかを確認するため、openssl_private_decrypt関数で秘密鍵を使って復号化する一連の処理も示されており、公開鍵暗号化の基本動作を学ぶのに適しています。

このサンプルコードは公開鍵暗号化の基本を示していますが、本番環境では鍵ペアをセキュアに生成・管理し、秘密鍵は決して公開せず厳重に保管する必要があります。openssl_public_encryptで暗号化できるデータサイズには鍵長に応じた制限があるため、大きなデータは共通鍵暗号とのハイブリッド方式を検討してください。暗号化と復号化で同じパディング方式を指定することが不可欠です。関数が失敗した際は、openssl_error_string()で詳細なエラー情報を確認し、適切にエラー処理を行うことが重要です。

PHPでRSA公開鍵暗号化する

1<?php
2
3/**
4 * 指定されたデータをRSA公開鍵で暗号化します。
5 *
6 * この関数は、一時的なRSA鍵ペアを生成し、その公開鍵を使用してデータを暗号化します。
7 * 暗号化されたデータは、通常、対応する秘密鍵で復号されます。
8 *
9 * @param string $dataToEncrypt 暗号化する元の文字列データ。
10 * @return string|false 暗号化されたデータ(Base64エンコード)、または処理失敗時にfalse。
11 */
12function encryptDataWithPublicKey(string $dataToEncrypt): string|false
13{
14    // 1. RSA鍵ペアの生成
15    // openssl_pkey_new() は、公開鍵と秘密鍵のペアを生成します。
16    // ここでは2048ビットのRSA鍵を生成します。
17    $res = openssl_pkey_new([
18        'private_key_bits' => 2048,
19        'private_key_type' => OPENSSL_KEYTYPE_RSA,
20    ]);
21
22    if ($res === false) {
23        // 鍵生成に失敗した場合のエラー処理
24        error_log("鍵ペアの生成に失敗しました: " . openssl_error_string());
25        return false;
26    }
27
28    // 2. 生成された鍵ペアから公開鍵の詳細を取得
29    // openssl_pkey_get_details() は、鍵の詳細情報を含む配列を返します。
30    // 'key' エントリに PEM 形式の公開鍵が含まれています。
31    $details = openssl_pkey_get_details($res);
32    if ($details === false || !isset($details['key'])) {
33        // 公開鍵の取得に失敗した場合のエラー処理
34        error_log("公開鍵の取得に失敗しました。");
35        openssl_pkey_free($res); // 鍵リソースを解放
36        return false;
37    }
38    $publicKey = $details['key'];
39
40    // 暗号化されたデータを格納するための変数
41    $encryptedData = '';
42
43    // 3. openssl_public_encrypt 関数を使用してデータを公開鍵で暗号化
44    // 第1引数: 暗号化する元のデータ ($dataToEncrypt)
45    // 第2引数: 暗号化されたデータが格納される参照変数 ($encryptedData)
46    // 第3引数: 使用する公開鍵 ($publicKey)
47    // 第4引数: パディングモード (OPENSSL_PKCS1_PADDING はRSA標準のパディング方式)
48    $success = openssl_public_encrypt(
49        $dataToEncrypt,
50        $encryptedData,
51        $publicKey,
52        OPENSSL_PKCS1_PADDING
53    );
54
55    // 鍵リソースを解放 (メモリリークを防ぐため)
56    openssl_pkey_free($res);
57
58    if ($success) {
59        // 暗号化されたデータはバイナリ形式のため、表示や転送のためにBase64エンコードします。
60        return base64_encode($encryptedData);
61    } else {
62        // 暗号化に失敗した場合のエラー処理
63        error_log("データの公開鍵暗号化に失敗しました: " . openssl_error_string());
64        return false;
65    }
66}
67
68// --- サンプルコードの実行 ---
69
70// 暗号化したい元のデータ
71$originalMessage = "This is a secret message that needs to be protected.";
72echo "元のデータ: " . $originalMessage . "\n\n";
73
74// 関数を呼び出してデータを暗号化
75$encryptedResult = encryptDataWithPublicKey($originalMessage);
76
77if ($encryptedResult !== false) {
78    echo "--- 暗号化成功 ---\n";
79    echo "暗号化されたデータ (Base64エンコード): " . $encryptedResult . "\n";
80    echo "\n注意: このサンプルでは復号を行っていませんが、通常は対応する秘密鍵で復号します。\n";
81} else {
82    echo "--- 暗号化失敗 ---\n";
83    echo "データの暗号化に失敗しました。エラーログを確認してください。\n";
84}
85
86?>

PHPのopenssl_public_encrypt関数は、RSA公開鍵暗号化の仕組みを利用してデータを安全に暗号化するために使用されます。この関数は、公開鍵で暗号化されたデータを、対応する秘密鍵でのみ復号できるという特性を持っています。具体的な機能として、第1引数に指定された元のデータ($data)を、第3引数で渡された公開鍵($public_key)を用いて暗号化します。暗号化された結果のデータは、第2引数の参照変数(&$encrypted_data)に格納されます。第4引数($padding)には、暗号化の際のパディング方式を指定し、通常はOPENSSL_PKCS1_PADDINGを選びます。処理が成功した場合はtrueを、失敗した場合はfalseを返します。

提供されたサンプルコードでは、openssl_pkey_new関数で一時的なRSA鍵ペアを生成し、その中からopenssl_pkey_get_detailsで公開鍵を取り出しています。そして、この公開鍵と元のメッセージをopenssl_public_encryptに渡して暗号化を実行しています。暗号化されたデータはバイナリ形式のため、通常はbase64_encodeでBase64エンコードしてから扱います。また、鍵リソースは処理後にopenssl_pkey_freeで解放し、エラー発生時にはopenssl_error_stringで原因を確認するよう実装されています。

このサンプルコードは一時的なRSA鍵ペアを生成して公開鍵暗号化を行っていますが、実際のアプリケーションでは鍵ペアは事前に生成し、秘密鍵は厳重に管理する必要があります。暗号化されたデータはバイナリ形式のため、データベース保存やネットワーク転送時にはBase64エンコードが必須です。openssl_public_encryptで直接暗号化できるデータ長には鍵長に応じた制限がありますので、大きなデータを扱う場合は共通鍵暗号と組み合わせるハイブリッド暗号方式の検討が必要です。常にエラーチェックを行い、使用後はopenssl_pkey_freeで鍵リソースを解放するようにしてください。復号には、この公開鍵に対応する秘密鍵が必要となります。

関連コンテンツ

関連プログラミング言語