Openssl free key: примеры (PHP)

Использование openssl_free_key для освобождения ресурсов ключей в PHP
Раздел: Шифрование (OpenSSL)
openssl_free_key(OpenSSLAsymmetricKey $key): void
Назначение и синтаксис функции openssl_free_key

Функция openssl_free_key освобождает память, занятую ресурсом открытого или закрытого ключа, созданным функциями вроде openssl_pkey_new() или openssl_pkey_get_private().

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

Аргументы:

  • OpenSSLAsymmetricKey|OpenSSLCertificate|resource $key – ресурс ключа, который требуется освободить. В PHP 8.0+ это может быть объект OpenSSLAsymmetricKey или OpenSSLCertificate.

Функция не возвращает значение (void).

Простые примеры применения
Освобождение ресурса закрытого ключа
<?php
// Создание нового ключа
$config = array(
    'digest_alg' => 'sha256',
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
);
$res = openssl_pkey_new($config);

// Получение деталей ключа
openssl_pkey_export($res, $privateKey);
$details = openssl_pkey_get_details($res);

// Освобождение ресурса
openssl_free_key($res);

// Проверка
var_dump($res);
?>
resource(5) of type (OpenSSL key)
Обработка открытого ключа из сертификата
<?php
$cert = file_get_contents('certificate.pem');
$pubKey = openssl_pkey_get_public($cert);

if ($pubKey !== false) {
    // Работа с ключом
    $data = 'test';
    openssl_public_encrypt($data, $encrypted, $pubKey);
    openssl_free_key($pubKey);
    echo 'Ключ освобожден';
}
?>
Ключ освобожден
Похожие функции в PHP

Прямых аналогов для освобождения ключей не существует, но есть функции для управления другими ресурсами OpenSSL.

  • openssl_free_x509() – освобождает ресурс сертификата X.509. Применяется для сертификатов, полученных через openssl_x509_read().
  • unset() – уничтожает переменную, но для ресурсов ключей в современных версиях PHP рекомендуется использовать openssl_free_key() для явного освобождения.
  • Сборка мусора PHP – автоматически освобождает ресурсы при завершении скрипта, однако в долгоживущих процессах лучше освобождать ключи вручную.
Распространенные ошибки
Передача неверного типа аргумента
<?php
$notAKey = 'some string';
openssl_free_key($notAKey);
?>
Warning: openssl_free_key(): supplied resource is not a valid OpenSSL key resource
Повторное освобождение ресурса
<?php
$key = openssl_pkey_new();
openssl_free_key($key);
openssl_free_key($key); // Вторая попытка
?>
Warning: openssl_free_key(): supplied resource is not a valid OpenSSL key resource
Использование освобожденного ключа
<?php
$key = openssl_pkey_new();
openssl_free_key($key);
$details = openssl_pkey_get_details($key);
?>
Warning: openssl_pkey_get_details(): supplied resource is not a valid OpenSSL key resource
Изменения в различных версиях PHP
  • PHP 8.0.0: Функция теперь принимает объекты OpenSSLAsymmetricKey или OpenSSLCertificate вместо ресурсов (resource). Вызов с устаревшим ресурсом по-прежнему работает, но выдает предупреждение о нежелательном использовании.
  • PHP 7.2.0: Функция была признана устаревшей (deprecated) для ресурсов, но это решение позже отменили, так как она осталась полезной для явного освобождения памяти.
Расширенные сценарии использования
Работа в цикле с множеством ключей
Пример php
<?php
for ($i = 0; $i < 100; $i++) {
    $key = openssl_pkey_new([
        'private_key_bits' => 1024,
        'private_key_type' => OPENSSL_KEYTYPE_RSA,
    ]);
    // Быстрые операции с ключом
    openssl_pkey_export($key, $pem);
    // Освобождение после каждой итерации
    openssl_free_key($key);
}
echo 'Создано и освобождено 100 ключей без утечек памяти';
?>
Создано и освобождено 100 ключей без утечек памяти
Обработка ключа из строки PEM
Пример php
<?php
$pemKey = '-----BEGIN PRIVATE KEY-----
...
-----END PRIVATE KEY-----';
$keyResource = openssl_pkey_get_private($pemKey);

if ($keyResource) {
    $data = 'Конфиденциальные данные';
    openssl_sign($data, $signature, $keyResource, OPENSSL_ALGO_SHA256);
    openssl_free_key($keyResource);
    echo 'Подпись создана, ресурс ключа освобожден';
}
?>
Подпись создана, ресурс ключа освобожден
Использование в классе с деструктором
Пример php
<?php
class KeyHandler {
    private $key;

    public function __construct() {
        $this->key = openssl_pkey_new();
    }

    public function getPublicKey() {
        return openssl_pkey_get_details($this->key)['key'];
    }

    public function __destruct() {
        if (is_resource($this->key) || $this->key instanceof OpenSSLAsymmetricKey) {
            openssl_free_key($this->key);
        }
    }
}

$handler = new KeyHandler();
echo $handler->getPublicKey();
// При уничтожении объекта ключ будет освобожден
unset($handler);
?>
-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----
Совместное использование с openssl_pkey_get_details
Пример php
<?php
$key = openssl_pkey_new(['private_key_bits' => 512]); // Малый ключ для примера
$details = openssl_pkey_get_details($key);

if ($details !== false) {
    echo 'Тип ключа: ' . $details['type'] . '\n';
    echo 'Биты: ' . $details['bits'] . '\n';
}

openssl_free_key($key);
echo 'Ресурс ключа освобожден';
?>
Тип ключа: 0
Биты: 512
Ресурс ключа освобожден
Аналоги в других языках программирования
Python (cryptography)
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.hazmat.backends import default_backend

# Создание ключа
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
    backend=default_backend()
)
# Удаление ссылки для сборки мусора
del private_key
print('Ключ удален')
Ключ удален
JavaScript (Node.js с модулем crypto)
const crypto = require('crypto');

// Генерация пары ключей
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
});

// Удаление ссылок
// В JavaScript память управляется сборщиком мусора,
// явного аналога openssl_free_key нет.
console.log('Ключи сгенерированы, память будет освобождена автоматически.');
Ключи сгенерированы, память будет освобождена автоматически.

Openssl free key в MySQL

В MySQL нет прямых аналогов, так как управление ключами происходит на уровне SQL-запросов (CREATE/DROP RSA KEY).

PHP openssl_free_key function comments

En
Openssl free key Free key resource