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

Полный разбор функции openssl_pkey_get_details в PHP
Раздел: Шифрование (OpenSSL)
openssl_pkey_get_details(OpenSSLAsymmetricKey $key): array|false

Описание функции openssl_pkey_get_details

Назначение

Функция openssl_pkey_get_details() возвращает массив с детальной информацией о ключе (открытом или закрытом). Она используется после получения ресурса ключа функциями openssl_pkey_get_public(), openssl_pkey_get_private() или openssl_pkey_new().

Аргументы функции

Функция принимает один обязательный аргумент:

  • $key (ресурс OpenSSL key) - ресурс, представляющий ключ, полученный одной из функций OpenSSL.

Функция возвращает ассоциативный массив с данными ключа или false в случае ошибки.

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

Пример с открытым ключом
// Пример для открытого ключа
$publicKey = openssl_pkey_get_public('file://path/to/public.pem');
$details = openssl_pkey_get_details($publicKey);
print_r($details);
Array
(
    [bits] => 2048
    [key] => -----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwZ...\n-----END PUBLIC KEY-----\n    [rsa] => Array
        (
            [n] => ...
            [e] => 65537
        )
    [type] => 0
)
Пример с закрытым ключом
// Пример для закрытого ключа
$privateKey = openssl_pkey_get_private('file://path/to/private.pem', 'passphrase');
$details = openssl_pkey_get_details($privateKey);
if ($details !== false) {
    echo 'Тип ключа: ' . $details['type'] . '\n';
    echo 'Длина ключа (бит): ' . $details['bits'] . '\n';
}
Тип ключа: 0
Длина ключа (бит): 2048

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

openssl_pkey_get_public и openssl_pkey_get_private

Эти функции используются для получения ресурса ключа из строки или файла, который затем можно передать в openssl_pkey_get_details(). Они являются предварительным шагом.

Функция openssl_pkey_export() экспортирует ключ в строку. В отличие от openssl_pkey_get_details(), она возвращает ключ в формате PEM, а не массив с деталями.

Выбор функции

openssl_pkey_get_details() применяется, когда нужна техническая информация о ключе (биты, тип, компоненты). Для получения ключа в строковом формате используют openssl_pkey_export.

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

Передача неверного типа аргумента
// Ошибка: передача строки вместо ресурса
$details = openssl_pkey_get_details('not_a_resource');
var_dump($details);
bool(false)
Использование неинициализированного ресурса
// Ошибка: ресурс уже освобожден
$key = openssl_pkey_get_public('file://public.pem');
openssl_free_key($key); // В PHP 8.0 и выше эта функция не требуется, но для примера
$details = openssl_pkey_get_details($key);
var_dump($details);
Warning: openssl_pkey_get_details(): supplied key param is not a valid key resource
bool(false)
Некорректный пароль для закрытого ключа
// Ошибка: неверный пароль
$key = openssl_pkey_get_private('file://private.pem', 'wrong_password');
if ($key === false) {
    echo 'Не удалось получить ключ.\n';
}
$details = openssl_pkey_get_details($key);
var_dump($details);
Не удалось получить ключ.
bool(false)

Изменения в последних версиях PHP

PHP 8.0.0

Параметр $key теперь ожидает экземпляр OpenSSLAsymmetricKey или OpenSSLCertificate (ранее ожидался ресурс (resource)). Функция openssl_free_key() стала устаревшей, так как ресурсы больше не используются.

Пример для PHP 8+
// В PHP 8+ ключ - это объект
$key = openssl_pkey_get_public('file://public.pem');
$details = openssl_pkey_get_details($key);
// Теперь $key - объект OpenSSLAsymmetricKey, а не ресурс
var_dump(gettype($key));
object(OpenSSLAsymmetricKey)

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

Извлечение компонентов RSA ключа
Пример php
// Детальное извлечение компонентов RSA
$privateKey = openssl_pkey_get_private('file://private_rsa.pem');
$details = openssl_pkey_get_details($privateKey);

if ($details && isset($details['rsa'])) {
    echo 'Модуль (n) в hex: ' . bin2hex($details['rsa']['n']) . '\n';
    echo 'Публичная экспонента (e): ' . $details['rsa']['e'] . '\n';
    // Для приватного ключа также доступны 'd', 'p', 'q', 'dmp1', 'dmq1', 'iqmp'
    if (isset($details['rsa']['d'])) {
        echo 'Приватная экспонента (d) присутствует\n';
    }
}
Модуль (n) в hex: a1b2c3...
Публичная экспонента (e): 65537
Приватная экспонента (d) присутствует
Работа с ключами EC (Elliptic Curve)
Пример php
// Для EC ключей структура массива отличается
$ecKey = openssl_pkey_get_private('file://ec_private.pem');
$details = openssl_pkey_get_details($ecKey);

if ($details && $details['type'] === OPENSSL_KEYTYPE_EC) {
    echo 'Тип ключа: EC\n';
    echo 'Длина ключа: ' . $details['bits'] . ' бит\n';
    echo 'Имя кривой: ' . $details['ec']['curve_name'] . '\n';
    echo 'Координата X: ' . bin2hex($details['ec']['x']) . '\n';
    echo 'Координата Y: ' . bin2hex($details['ec']['y']) . '\n';
}
Тип ключа: EC
Длина ключа: 256 бит
Имя кривой: prime256v1
Координата X: 7d3b...
Координата Y: 2a1f...
Проверка соответствия публичного и приватного ключей
Пример php
// Сравнение модулей RSA ключей
$publicKey = openssl_pkey_get_public('file://public.pem');
$privateKey = openssl_pkey_get_private('file://private.pem');

$publicDetails = openssl_pkey_get_details($publicKey);
$privateDetails = openssl_pkey_get_details($privateKey);

if ($publicDetails['rsa']['n'] === $privateDetails['rsa']['n']) {
    echo 'Ключи являются парой (модули совпадают).\n';
} else {
    echo 'Ключи не являются парой.\n';
}
Ключи являются парой (модули совпадают).
Генерация нового ключа и получение его деталей
Пример php
// Генерация нового RSA ключа
$config = array(
    'digest_alg' => 'sha256',
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
);

$newKey = openssl_pkey_new($config);
$details = openssl_pkey_get_details($newKey);

echo 'Сгенерирован ключ длиной: ' . $details['bits'] . ' бит\n';
// Экспорт публичного ключа
$publicKeyPem = $details['key'];
echo 'Публичный ключ в PEM:\n' . $publicKeyPem;
Сгенерирован ключ длиной: 2048 бит
Публичный ключ в PEM:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwZ...
-----END PUBLIC KEY-----

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

Python (cryptography)
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend

with open("public.pem", "rb") as key_file:
    public_key = serialization.load_pem_public_key(
        key_file.read(),
        backend=default_backend()
    )
public_numbers = public_key.public_numbers()
print(f"Modulus: {public_numbers.n}")
print(f"Exponent: {public_numbers.e}")
JavaScript (Node.js с crypto)
const crypto = require('crypto');
const fs = require('fs');

const publicKeyPem = fs.readFileSync('public.pem', 'utf8');
const publicKey = crypto.createPublicKey(publicKeyPem);
console.log(publicKey.asymmetricKeyType); // 'rsa'
console.log(publicKey.asymmetricKeyDetails); // { modulusLength: 2048, publicExponent: 65537n }
Отличия от PHP

В Python и JavaScript работа с ключами часто более объектно-ориентирована. В PHP функция возвращает простой ассоциативный массив, что может быть удобно для быстрого получения данных.

PHP openssl_pkey_get_details function comments

En
Openssl pkey get details Returns an array with the key details