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

Экспорт закрытых ключей в PHP с openssl_pkey_export_to_file
Раздел: Шифрование (OpenSSL)
openssl_pkey_export_to_file(OpenSSLAsymmetricKey $key, string $output_filename, ?string $passphrase = null, ?array $options = null): bool
Функция openssl_pkey_export_to_file

Функция openssl_pkey_export_to_file в языке PHP экспортирует закрытый ключ в файл. Применение функции встречается в задачах, связанных с криптографией, например при создании пары ключей для шифрования или подписи данных. Функция сохраняет ключ в формате PEM.

Аргументы функции
  • $key: Ресурс ключа или массив с данными ключа. Содержит закрытый ключ для экспорта.
  • $output_filename: Строка. Путь к файлу, в который будет записан ключ.
  • $passphrase (опциональный): Строка. Парольная фраза для шифрования закрытого ключа. Если аргумент не задан, ключ сохраняется без шифрования.
  • $options (опциональный): Массив. Настройки для экспорта. Может включать параметры, такие как "encrypt_key" или "encrypt_key_cipher".

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

Примеры использования
Базовый пример экспорта ключа

Создание и сохранение ключа без пароля.

<?php
// Генерация новой пары ключей
$config = array(
    "digest_alg" => "sha256",
    "private_key_bits" => 2048,
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
);
$keyPair = openssl_pkey_new($config);

// Экспорт закрытого ключа в файл
$result = openssl_pkey_export_to_file($keyPair, 'private_key.pem');

if ($result) {
    echo "Ключ сохранён.";
} else {
    echo "Ошибка экспорта.";
}
?>
Ключ сохранён.
Экспорт с парольной фразой
<?php
$config = array("private_key_bits" => 1024);
$keyPair = openssl_pkey_new($config);

// Экспорт с паролем
$result = openssl_pkey_export_to_file($keyPair, 'encrypted_key.pem', 'mySecretPassword');

var_dump($result);
?>
bool(true)
Использование массива конфигурации
<?php
$keyData = array(
    "digest_alg" => "sha512",
    "private_key_type" => OPENSSL_KEYTYPE_EC,
    "curve_name" => "prime256v1"
);
$keyPair = openssl_pkey_new($keyData);

$options = array("encrypt_key" => true);
$result = openssl_pkey_export_to_file($keyPair, 'ec_key.pem', null, $options);
?>
// Файл создан.
Похожие функции в PHP
  • openssl_pkey_export(): Экспортирует ключ в строку вместо файла. Используется, когда нужно получить ключ в виде переменной.
  • openssl_pkey_get_details(): Возвращает массив с деталями ключа, включая открытый ключ. Полезна для извлечения компонентов ключа.
  • openssl_pkey_get_private() и openssl_pkey_get_public(): Получают ресурс ключа из файла или строки. Применяются для загрузки ранее сохранённых ключей.

Выбор функции зависит от задачи: openssl_pkey_export_to_file предпочтительна для прямого сохранения в файл, а openssl_pkey_export() — для обработки ключа в памяти.

Распространённые ошибки
Неверный ресурс ключа
<?php
$result = openssl_pkey_export_to_file("not_a_key", 'key.pem');
var_dump($result);
?>
Warning: openssl_pkey_export_to_file(): cannot get key from parameter 1
bool(false)
Проблемы с правами доступа к файлу
<?php
$keyPair = openssl_pkey_new(array("private_key_bits" => 512));
// Попытка записи в системную директорию
$result = openssl_pkey_export_to_file($keyPair, '/root/key.pem');
if (!$result) {
    echo "Ошибка записи файла. Проверьте права.";
}
?>
Ошибка записи файла. Проверьте права.
Несуществующая директория для файла
<?php
$keyPair = openssl_pkey_new(array("private_key_bits" => 512));
$result = openssl_pkey_export_to_file($keyPair, '/nonexistent/folder/key.pem');
var_dump($result);
?>
bool(false)
Изменения в версиях PHP

В PHP 8.0.0 аргумент $passphrase теперь допускает значение null. Ранее ожидалась строка.

В PHP 7.3.0 параметр $options стал необязательным.

Функция сохраняет обратную совместимость, поведение основных аргументов не менялось.

Расширенные примеры
Экспорт ключа из существующего PEM файла
Пример php
<?php
// Загрузка ключа из файла
$privateKey = openssl_pkey_get_private(file_get_contents('existing_key.pem'));

// Экспорт в новый файл с паролем
$options = array(
    "encrypt_key" => true,
    "encrypt_key_cipher" => OPENSSL_CIPHER_AES_256_CBC
);
$success = openssl_pkey_export_to_file($privateKey, 'new_encrypted.pem', 'newpass', $options);

if ($success) {
    echo "Ключ пересохранён с новым паролем.";
}
?>
Ключ пересохранён с новым паролем.
Создание и экспорт нескольких ключей
Пример php
<?php
$keyTypes = [
    ["type" => OPENSSL_KEYTYPE_RSA, "bits" => 2048, "name" => "rsa"],
    ["type" => OPENSSL_KEYTYPE_DSA, "bits" => 1024, "name" => "dsa"],
];

foreach ($keyTypes as $spec) {
    $config = [
        "private_key_bits" => $spec['bits'],
        "private_key_type" => $spec['type'],
    ];
    $key = openssl_pkey_new($config);
    if ($key) {
        $filename = $spec['name'] . '_key.pem';
        openssl_pkey_export_to_file($key, $filename);
        echo "Создан файл: $filename<br>";
    }
}
?>
Создан файл: rsa_key.pem
Создан файл: dsa_key.pem
Экспорт с использованием пользовательского обработчика ошибок
Пример php
<?php
set_error_handler(function($errno, $errstr) {
    echo "Ошибка OpenSSL: $errstr";
});

$key = openssl_pkey_new(['private_key_bits' => 512]);
// Неверный аргумент для passphrase (не строка)
$result = openssl_pkey_export_to_file($key, 'test.pem', ['array']);

restore_error_handler();
var_dump($result);
?>
Ошибка OpenSSL: openssl_pkey_export_to_file(): Passphrase must be a string
bool(false)
Аналоги в других языках
Python (cryptography)
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.primitives import serialization

private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)

with open("private_key.pem", "wb") as f:
    f.write(private_key.private_bytes(
        encoding=serialization.Encoding.PEM,
        format=serialization.PrivateFormat.TraditionalOpenSSL,
        encryption_algorithm=serialization.NoEncryption()
    ))
print("Файл создан.")
Файл создан.
JavaScript (Node.js с модулем crypto)
const crypto = require('crypto');
const fs = require('fs');

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

fs.writeFileSync('private_key.pem', privateKey.export({
    type: 'pkcs1',
    format: 'pem'
}));
console.log('Экспорт завершён.');
Экспорт завершён.

Openssl pkey export to file в MySQL

Прямого аналога нет. Ключи обычно генерируются внешними средствами и импортируются через SQL-запросы CREATE SSL.

PHP openssl_pkey_export_to_file function comments

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