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

作成日: 更新日:

openssl_pkey_get_private関数は、PEM形式でエンコードされた秘密鍵を解析し、PHPで利用可能なキーリソースを取得する関数です。この関数は、ファイルや文字列として与えられた秘密鍵を読み込み、後続の暗号化や署名処理で使用できる形式に変換する役割を持ちます。第一引数には、秘密鍵のデータを含む文字列、またはfile://から始まるファイルへのパスを指定します。もし秘密鍵がパスフレーズ(パスワード)によって保護されている場合は、第二引数にそのパスフレーズを文字列で指定する必要があります。鍵が暗号化されていない場合は、この引数は不要です。関数の実行に成功すると、他のOpenSSL関数で使用できるOpenSSLAsymmetricKeyオブジェクト(PHP 8.0.0より前のバージョンではリソース型)が返されます。一方で、鍵の形式が不正であったり、指定したパスフレーズが間違っていたりして解析に失敗した場合はfalseを返します。この関数で取得したキーは、主にopenssl_sign関数によるデータ署名の生成や、openssl_private_encrypt関数によるデータの暗号化といった、セキュリティが求められる処理に利用されます。

基本的な使い方

構文(syntax)

$private_key_resource = openssl_pkey_get_private(
    '-----BEGIN PRIVATE KEY-----...', // 秘密鍵の文字列、または file:// で始まるパス
    'your-passphrase'                 // 秘密鍵が暗号化されている場合のパスフレーズ (任意)
);

引数(parameters)

OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key, ?string $passphrase = null

  • OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key: 秘密鍵を指定します。OpenSSLAsymmetricKey オブジェクト、OpenSSLCertificate オブジェクト、または秘密鍵を表す配列または文字列で指定できます。
  • ?string $passphrase = null: 秘密鍵がパスワードで保護されている場合、そのパスワードを指定します。パスワードがない場合は null または省略します。

戻り値(return)

OpenSSLAsymmetricKey|false

openssl_pkey_get_private関数は、秘密鍵を操作するためのOpenSSLAsymmetricKeyオブジェクト、またはエラー発生時にはfalseを返します。

サンプルコード

openssl_pkey_get_privateでプライベートキーを読み込む

<?php

/**
 * openssl_pkey_get_private関数の使用例。
 * このスクリプトは、パスフレーズで保護されたPEM形式のプライベートキー文字列を読み込み、
 * OpenSSLAsymmetricKeyオブジェクトを取得する方法を示します。
 */

// 1. サンプル用のプライベートキーを生成します。
//    通常、プライベートキーはファイルから読み込むか、セキュアなストレージから取得します。
//    ここでは、スクリプト実行時に一時的に生成します。
$configArgs = [
    "digest_alg"       => "sha256",          // ハッシュアルゴリズム
    "private_key_bits" => 2048,              // キーのビット長
    "private_key_type" => OPENSSL_KEYTYPE_RSA, // キータイプ(RSA)
];

// 新しいキーペアオブジェクトを生成します。
// PHP 8.0以降ではOpenSSLAsymmetricKeyオブジェクトを返します。
$newKeyPair = openssl_pkey_new($configArgs);

if ($newKeyPair === false) {
    die("エラー: プライベートキーの生成に失敗しました。" . PHP_EOL);
}

// プライベートキーを保護するためのパスフレーズ。
// 実際の運用では、より複雑でセキュアなパスフレーズを使用してください。
$passphrase = 'YourSecureAndComplexPassphraseHere';

// 生成したプライベートキーをPEM形式の文字列としてエクスポートします。
// エクスポート時にパスフレーズで保護されます。
$privateKeyString = '';
if (!openssl_pkey_export($newKeyPair, $privateKeyString, $passphrase)) {
    die("エラー: プライベートキーのエクスポートに失敗しました。" . PHP_EOL);
}

echo "--- プライベートキーの読み込みを開始します ---" . PHP_EOL;

// 2. openssl_pkey_get_private関数を使用して、PEM形式のプライベートキー文字列を読み込みます。
//    第一引数にプライベートキーの文字列、第二引数にパスフレーズを渡します。
//    成功するとOpenSSLAsymmetricKeyオブジェクトを、失敗するとfalseを返します。
$privateKeyObject = openssl_pkey_get_private($privateKeyString, $passphrase);

// 3. 処理結果を確認し、読み込みが成功した場合はキー情報を表示します。
if ($privateKeyObject === false) {
    echo "エラー: プライベートキーの読み込みに失敗しました。" . PHP_EOL;
    // OpenSSLのエラーキューからエラーメッセージをすべて取得して表示します。
    while ($msg = openssl_error_string()) {
        echo "OpenSSLエラー: " . $msg . PHP_EOL;
    }
} else {
    echo "プライベートキーが正常に読み込まれました (OpenSSLAsymmetricKeyオブジェクトとして)。" . PHP_EOL;

    // 読み込んだキーの詳細情報を取得します。
    $keyDetails = openssl_pkey_get_details($privateKeyObject);

    if ($keyDetails !== false) {
        echo "--- キー詳細 ---" . PHP_EOL;
        echo "タイプ: ";
        switch ($keyDetails['type']) {
            case OPENSSL_KEYTYPE_RSA:
                echo "RSA";
                break;
            case OPENSSL_KEYTYPE_DSA:
                echo "DSA";
                break;
            case OPENSSL_KEYTYPE_DH:
                echo "DH";
                break;
            case OPENSSL_KEYTYPE_EC:
                echo "EC";
                break;
            default:
                echo "不明";
                break;
        }
        echo PHP_EOL;
        echo "ビット数: " . $keyDetails['bits'] . PHP_EOL;
        echo "--- ---" . PHP_EOL;
    } else {
        echo "エラー: キーの詳細情報の取得に失敗しました。" . PHP_EOL;
        while ($msg = openssl_error_string()) {
            echo "OpenSSLエラー: " . $msg . PHP_EOL;
        }
    }
}

echo "--- 処理を終了します ---" . PHP_EOL;

?>

PHPのopenssl_pkey_get_private関数は、OpenSSLのプライベートキー情報をPHPが扱えるOpenSSLAsymmetricKeyオブジェクトとして読み込むために使用されます。これにより、暗号化やデジタル署名など、セキュリティ関連の様々な操作でプライベートキーを活用できるようになります。

第一引数には、読み込みたいプライベートキーの情報を指定します。これはPEM形式の文字列、OpenSSLAsymmetricKeyオブジェクト、OpenSSLCertificateオブジェクト、またはキー設定を含む配列のいずれかで渡すことができます。サンプルコードでは、パスフレーズで保護されたPEM形式のプライベートキー文字列を渡しています。

第二引数には、プライベートキーがパスフレーズで保護されている場合に、そのパスフレーズを文字列で指定します。プライベートキーがパスフレーズで保護されていない場合は、この引数は省略可能です。

関数が正常にプライベートキーを読み込めた場合、そのプライベートキーを表すOpenSSLAsymmetricKeyオブジェクトを返します。読み込みに失敗した場合はfalseを返しますので、戻り値の確認は重要です。

サンプルコードでは、まず一時的にプライベートキーを生成し、それをパスフレーズ付きのPEM形式文字列としてエクスポートします。その後、openssl_pkey_get_private関数にこの文字列とパスフレーズを渡して、OpenSSLAsymmetricKeyオブジェクトとして再読み込みし、その詳細情報を表示する流れを示しています。これにより、外部から取得したプライベートキーをPHPのプログラム内で安全に利用する基本的な方法を理解できます。

openssl_pkey_get_private関数は、パスフレーズで保護されたPEM形式のプライベートキー文字列を、OpenSSLAsymmetricKeyオブジェクトとして安全に読み込む際に利用します。関数がfalseを返す場合はキーの読み込みに失敗しているため、必ず厳密なエラーチェックを行ってください。失敗時にはopenssl_error_string()関数を利用することで、OpenSSLが報告する詳細なエラーメッセージを確認できます。本番環境で利用するプライベートキーは、ファイルなどからセキュアな方法で取得し、パスフレーズも複雑で漏洩しにくいものを設定して厳重に管理することが極めて重要です。パスフレーズが誤っていると読み込みは失敗しますのでご注意ください。

openssl_pkey_get_privateで秘密鍵を読み込む

<?php

/**
 * Demonstrates the usage of openssl_pkey_get_private to load a private key from a string,
 * including how to handle success and failure scenarios (e.g., "not working").
 *
 * This example generates a test private key internally to be self-contained and
 * guarantee a valid input for demonstration purposes.
 */
function demonstratePrivateKeyLoading(): void
{
    echo "--- Demonstration of openssl_pkey_get_private ---\n\n";

    // --- Step 1: Generate a test private key for demonstration ---
    // In a real-world application, you would typically load a private key
    // from a file or configuration. For this self-contained example,
    // we generate a temporary RSA key.
    $config = [
        "digest_alg" => "sha512",
        "private_key_bits" => 2048,
        "private_key_type" => OPENSSL_KEYTYPE_RSA,
    ];

    // Generate a new private key resource.
    $keyResource = openssl_pkey_new($config);
    if ($keyResource === false) {
        echo "Error: Failed to generate a new private key for the demo.\n";
        while ($msg = openssl_error_string()) {
            echo "OpenSSL error: " . $msg . "\n";
        }
        return;
    }

    $passphrase = 'a_strong_demo_passphrase'; // A passphrase for the generated key
    $privateKeyString = '';

    // Export the generated private key into a string (PEM format) with the passphrase.
    if (!openssl_pkey_export($keyResource, $privateKeyString, $passphrase)) {
        echo "Error: Failed to export the generated private key string.\n";
        while ($msg = openssl_error_string()) {
            echo "OpenSSL error: " . $msg . "\n";
        }
        openssl_pkey_free($keyResource); // Free the key resource
        return;
    }
    openssl_pkey_free($keyResource); // Free the initial key resource after export

    // --- Step 2: Attempt to load the private key successfully with the correct passphrase ---
    echo "Scenario 1: Loading private key with the CORRECT passphrase.\n";
    echo "--------------------------------------------------------\n";
    $loadedKey = openssl_pkey_get_private($privateKeyString, $passphrase);

    if ($loadedKey === false) {
        // If openssl_pkey_get_private returns false, an error occurred.
        // This indicates a "not working" situation.
        echo "Failure: Failed to load private key with the correct passphrase.\n";
        echo "Error details (important for debugging 'not working' issues):\n";
        // Loop through and display all OpenSSL error messages for debugging.
        while ($msg = openssl_error_string()) {
            echo "- " . $msg . "\n";
        }
    } else {
        echo "Success: Private key loaded successfully!\n";
        // The $loadedKey is now an OpenSSLAsymmetricKey object, which can be used
        // for operations like signing, decryption, or getting key details.
        $details = openssl_pkey_get_details($loadedKey);
        if ($details) {
            echo "Key type: " . ($details['type'] === OPENSSL_KEYTYPE_RSA ? 'RSA' : 'Other') . "\n";
            echo "Key bits: " . $details['bits'] . "\n";
        }
        openssl_pkey_free($loadedKey); // It's good practice to free the key resource when done.
    }

    echo "\n";

    // --- Step 3: Demonstrate "not working" with an INCORRECT passphrase ---
    echo "Scenario 2: Loading private key with an INCORRECT passphrase (expected failure).\n";
    echo "----------------------------------------------------------------------\n";
    $incorrectPassphrase = 'this_is_the_wrong_passphrase';
    $failedLoadedKey = openssl_pkey_get_private($privateKeyString, $incorrectPassphrase);

    if ($failedLoadedKey === false) {
        // This is the expected outcome when the passphrase is wrong.
        echo "Success (expected failure): Private key failed to load with the incorrect passphrase.\n";
        echo "Error details (identifying the 'not working' cause):\n";
        // Displaying error messages helps diagnose why it "not working".
        while ($msg = openssl_error_string()) {
            echo "- " . $msg . "\n";
        }
    } else {
        // This scenario would be an unexpected security issue if it happened.
        echo "Failure (unexpected success): Private key loaded even with an incorrect passphrase!\n";
        openssl_pkey_free($failedLoadedKey);
    }

    echo "\n--- End of demonstration ---\n";
}

// Execute the demonstration function.
demonstratePrivateKeyLoading();

?>

PHPのopenssl_pkey_get_private関数は、秘密鍵の文字列やファイルなどから秘密鍵リソース(OpenSSLAsymmetricKeyオブジェクト)を読み込むために使用されます。引数として、読み込みたい秘密鍵データ($private_key)を渡し、鍵がパスフレーズで暗号化されている場合は、そのパスフレーズ($passphrase)を指定します。

この関数は、秘密鍵が正しく読み込めた場合にOpenSSLAsymmetricKeyオブジェクトを返しますが、読み込みに失敗した場合はfalseを返します。特にパスフレーズが間違っている場合など、「not working」と感じるような失敗時にはfalseが返されます。このような状況では、openssl_error_string()関数を繰り返し呼び出すことで、OpenSSLライブラリから具体的なエラーメッセージを取得し、原因を特定することが重要です。

提示されたサンプルコードでは、まずデモンストレーション用に一時的な秘密鍵を生成し、パスフレーズ付きで文字列としてエクスポートしています。その後、シナリオ1として、その秘密鍵を正しいパスフレーズで読み込むことに成功する例を示し、正しく鍵がロードされた際に鍵の詳細情報が取得できることを確認しています。

次にシナリオ2として、同じ秘密鍵を「間違ったパスフレーズ」で読み込もうとする失敗例(「not working」の状況)を示しています。この場合、openssl_pkey_get_privatefalseを返し、openssl_error_string()によって「bad decrypt」などのエラーメッセージが出力されることを確認でき、これが問題解決の手がかりとなります。この関数は、主に署名や複合化といった暗号処理を行う前に、秘密鍵を安全にプログラム内にロードする際に利用されます。

openssl_pkey_get_private関数は、指定されたデータからプライベートキーを読み込む際に使用します。キーの読み込みに失敗した場合はfalseが返されるため、必ず戻り値をチェックし、エラーハンドリングを行うことが重要です。特に「not working」と感じた際には、openssl_error_string()関数をループで呼び出し、詳細なエラーメッセージを確認することで原因を特定できます。パスフレーズの誤入力はよくある失敗原因の一つです。取得したキーリソースは、処理が完了した後にopenssl_pkey_free()で明示的に解放することが推奨されます。実運用では、プライベートキーはファイルなど安全な場所からロードしてください。

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