Openssl pkey export: примеры (PHP)

Экспорт приватных ключей в PHP с использованием openssl_pkey_export
Раздел: Шифрование (OpenSSL)
openssl_pkey_export(OpenSSLAsymmetricKey $key, string &$output, ?string $passphrase = null, ?array $options = null): bool

Функция openssl_pkey_export

Функция openssl_pkey_export экспортирует закрытый ключ в строковый формат. Она используется для сохранения или передачи ключа в безопасном формате, например, в PEM-кодировке.

Аргументы функции
  • $key - ресурс ключа или массив с данными ключа.
  • &$output - переменная для записи результата (передается по ссылке).
  • $passphrase (необязательный) - парольная фраза для шифрования ключа.
  • $options (необязательный) - массив опций конфигурации.

Функция возвращает true при успехе и false при ошибке.

Примеры использования

Базовый пример
<?php
$config = [
    'digest_alg' => 'sha256',
    'private_key_bits' => 2048
];
$key = openssl_pkey_new($config);
openssl_pkey_export($key, $output);
echo $output;
?>
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5...
-----END PRIVATE KEY-----
С парольной фразой
<?php
$key = openssl_pkey_new();
openssl_pkey_export($key, $output, 'MySecretPass');
echo $output;
?>
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQI5cF5W6PZ3CkCAggA
...
-----END ENCRYPTED PRIVATE KEY-----

Похожие функции PHP

Возвращает массив с деталями ключа, но не экспортирует в PEM-формат.

Получает закрытый ключ из строки или файла, может использоваться для чтения экспортированных ключей.

Экспортирует ключ напрямую в файл, что удобно для сохранения на диск.

Типичные ошибки

Неверный тип ключа
<?php
$result = openssl_pkey_export('invalid_key', $output);
var_dump($result);
?>
bool(false)
Отсутствие расширения OpenSSL
<?php
// При отключенном расширении openssl
if (!extension_loaded('openssl')) {
    die('Расширение OpenSSL не доступно');
}
?>
Проблемы с конфигурацией
<?php
$config = ['config' => '/wrong/path/openssl.cnf'];
$key = openssl_pkey_new($config);
if (!$key) {
    echo openssl_error_string();
}
?>
error:02001003:system library:fopen:No such process

Изменения в версиях PHP

PHP 8.0

Тип параметра $key теперь может быть объектом OpenSSLAsymmetricKey или OpenSSLCertificate, а не только ресурсом.

PHP 7.3

Добавлена поддержка передачи массива конфигурации в параметре $options.

PHP 5.6

Параметр $passphrase стал необязательным, а функция начала возвращать boolean вместо void.

Расширенные примеры

Экспорт ключа из сертификата
Пример php
<?php
$cert = file_get_contents('certificate.pem');
$key = openssl_pkey_get_private($cert, 'passphrase');
openssl_pkey_export($key, $output, 'new_passphrase');
file_put_contents('exported_key.pem', $output);
?>
Работа с EC-ключами
Пример php
<?php
$config = [
    'curve_name' => 'prime256v1',
    'private_key_type' => OPENSSL_KEYTYPE_EC
];
$key = openssl_pkey_new($config);
openssl_pkey_export($key, $ecKey);
echo $ecKey;
?>
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIMQqPELhPbC4jI4RfX8r6M7JHCEv5pP5Z5q6KZ6Q7hPNoAoGCCqGSM49
AwEHoUQDQgAE5X+3NlQK8QaQzZQ9Q8Q9Q8Q9Q8Q9Q8Q9Q8Q9Q8Q9Q8Q9Q8Q9Q8Q9
...
-----END EC PRIVATE KEY-----
Использование callback для passphrase
Пример php
<?php
$key = openssl_pkey_new();
$passphrase = 'secret';
openssl_pkey_export($key, $output, $passphrase, [
    'encrypt_key' => true,
    'config' => '/etc/ssl/openssl.cnf'
]);
// Проверка экспортированного ключа
$imported = openssl_pkey_get_private($output, $passphrase);
var_dump($imported !== false);
?>
bool(true)

Альтернативы в других языках

Python (cryptography)
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import rsa

key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
pem = key.private_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PrivateFormat.PKCS8,
    encryption_algorithm=serialization.NoEncryption()
)
print(pem.decode())
JavaScript (Node.js crypto)
const { generateKeyPairSync, privateEncrypt } = require('crypto');

const { privateKey } = generateKeyPairSync('rsa', {
    modulusLength: 2048
});

const pem = privateKey.export({
    type: 'pkcs1',
    format: 'pem'
});
console.log(pem);

Openssl pkey export в MySQL

MySQL не имеет прямой аналогии, но поддерживает хранение ключей в таблицах через функции CREATE_ASYMMETRIC_PRIV_KEY.

PHP openssl_pkey_export function comments

En
Openssl pkey export Gets an exportable representation of a key into a string