パスフレーズ付きの秘密鍵を読み込むには

ある外部サービスのAPIを呼ぶために、その外部サービス用の秘密鍵をサーバに配置しなければいけません。

そこで、秘密鍵にパスフレーズを付けることにしました。パスフレーズは環境変数で渡すことにしました。

秘密鍵にパスフレーズをつけるには

(1)パスフレーズなしの秘密鍵ファイルのフィンガープリントを表示します。

$ ssh-keygen -l -f fuga.pem
2048 SHA256:jbfeqqCujAK6A/qBg0+FkF2IydwRlUPoMyjWEgHULwo no comment (RSA)Code language: Bash (bash)

(2)パスフレーズなしの秘密鍵ファイルをコピーします。

$ cp fuga.pem fuga_with_passphrase.pemCode language: Bash (bash)

(3)コピーした秘密鍵ファイルにパスフレーズをつけます。

$ ssh-keygen -p -f fuga.pem
Enter new passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved with the new passphrase.Code language: Bash (bash)

(4)フィンガープリントを表示します。(1)のパスフレーズなしの秘密鍵ファイルのフィンガープリントと同じことを確認しましょう。

$ ssh-keygen -l -f fuga_with_passphrase.pem
Enter PEM pass phrase:
2048 SHA256:jbfeqqCujAK6A/qBg0+FkF2IydwRlUPoMyjWEgHULwo no comment (RSA)Code language: Bash (bash)

パスフレーズ付きの秘密鍵を読み込むには

その外部サービスでは、$fuga_setting['private_key']に秘密鍵ファイルのパス、または、秘密鍵の内容を設定します。

まず、パスフレーズなしの秘密鍵でAPIが動くかを確認します。

<?php

$fuga_setting['private_key'] = __DIR__ . '/fuga.pem';
$client = Fuga\API\Client($fuga_setting);
$client->getFuga(...);Code language: PHP (php)

次に、private_key にパスフレーズなしの秘密鍵の内容を読み込んでみます。

<?php

$fuga_setting['private_key'] = __DIR__ . '/fuga.pem';
$fuga_setting['private_key'] = file_get_contents($fuga_setting['private_key']);
$client = Fuga\API\Client($fuga_setting);
$client->getFuga(...);Code language: PHP (php)

最後に、パスフレーズ付きの秘密鍵を使うようにします。

<?php

$fuga_setting['private_key'] = __DIR__ . '/fuga_with_passphrase.pem';

$pkey = openssl_pkey_get_private($path, "fu****ga");
openssl_pkey_export($pkey, $out);
$fuga_setting['private_key'] = $out;

$client = Fuga\API\Client($fuga_setting);
$client->getFuga(...);Code language: PHP (php)

メソッドに分けておきましょう。

<?php

$fuga_setting['private_key'] = __DIR__ . '/fuga_with_passphrase.pem';

$fuga_setting['private_key'] = loadPrivatekeyWithPassphrase(
    $fuga_setting['private_key'],
    "fu****ga"
);

$client = Fuga\API\Client($fuga_setting);
$client->getFuga(...);

/**
 * @param string $path
 * @param string $passphrase
 */
function loadPrivatekeyWithPassphrase($path, $passphrase)
{
    $pkey = openssl_pkey_get_private($path, $passphrase);
    $out = "";
    openssl_pkey_export($pkey, $out);
    return $out;
}

Code language: PHP (php)

パスフレーズを環境変数から取得するようにします。

<?php

$fuga_setting['private_key'] = __DIR__ . '/fuga_with_passphrase.pem';

$passphrase = getenv('FUGA_PASSPHRASE');
$fuga_setting['private_key'] = loadPrivatekeyWithPassphrase(
    $fuga_setting['private_key'],
    $passphrase
);

$client = Fuga\API\Client($fuga_setting);
$client->getFuga(...);

/**
 * @param string $path
 * @param string $passphrase
 */
function loadPrivatekeyWithPassphrase($path, $passphrase)
{
    $pkey = openssl_pkey_get_private($path, $passphrase);
    $out = "";
    openssl_pkey_export($pkey, $out);
    return $out;
}

Code language: PHP (php)

openssl-pkey-get-private

openssl-pkey-export

たった2つの関数を呼ぶだけなんだけど、動くまでに時間がかかったよ

環境変数にパスフレーズを設定するには

AWS ElasticBeanstalkなら、コンソールで環境変数を設定します。

ローカルのdocker環境なら、docker-compose.ymlで設定します。

services:
  web:
    ...

    environment:
      - FUGA_PASSPHRASE=fu****ga
Code language: YAML (yaml)

PHPで一時的に設定したい場合は、putenv関数を使います。

<?php

putenv('FUGA_PASSPHRASE=fu****ga');

// 試しに echo してみる
echo getenv('FUGA_PASSPHRASE');
Code language: PHP (php)
タイトルとURLをコピーしました