Openssl csr sign: примеры (PHP)

Функция openssl_csr_sign: практическое руководство с примерами
Раздел: Шифрование (OpenSSL)
openssl_csr_sign(OpenSSLCertificateSigningRequest|string $csr, OpenSSLCertificate|string|null $ca_certificate, OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key, int $days, ?array $options = null, int $serial = 0): OpenSSLCertificate|false

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

Функция openssl_csr_sign создает сертификат X.509 на основе предоставленного запроса на подпись сертификата (CSR). Она используется в процессах выпуска цифровых сертификатов центром сертификации (CA).

Аргументы функции
  • $csr (string|OpenSSLCertificateSigningRequest) - Запрос на подпись сертификата, созданный функцией openssl_csr_new.
  • $ca_cert (string|OpenSSLCertificate|null) - Сертификат центра сертификации, используемый для подписи. Может быть null для самоподписанных сертификатов.
  • $private_key (string|OpenSSLAsymmetricKey|OpenSSLCertificate|array) - Закрытый ключ, соответствующий сертификату CA.
  • $days (int) - Срок действия подписанного сертификата в днях.
  • $options (array|null) - Дополнительные опции для настройки сертификата (например, config, digest_alg).
  • $serial (int) - Серийный номер сертификата. По умолчанию 0, что генерирует случайный номер.

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

Создание самоподписанного сертификата
<?php
// Создание пары ключей и CSR
$private_key = openssl_pkey_new([
    'private_key_bits' => 2048,
    'private_key_type' => OPENSSL_KEYTYPE_RSA,
]);

$dn = [
    'commonName' => 'example.com',
];
$csr = openssl_csr_new($dn, $private_key);

// Подпись CSR (самоподписанный)
$cert = openssl_csr_sign($csr, null, $private_key, 365);

openssl_x509_export($cert, $cert_out);
echo $cert_out;
?>
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIUYc...
-----END CERTIFICATE-----
Подпись CSR сертификатом CA
<?php
// Загрузка CA ключа и сертификата
$ca_key = openssl_pkey_get_private('file://ca_private.key');
$ca_cert = openssl_x509_read(file_get_contents('ca_certificate.crt'));

// Загрузка CSR из файла
$csr = openssl_csr_read(file_get_contents('request.csr'));

$cert = openssl_csr_sign(
    $csr,
    $ca_cert,
    $ca_key,
    730, // 2 года
    ['digest_alg' => 'sha256'],
    1234567890 // серийный номер
);

openssl_x509_export_to_file($cert, 'signed_cert.crt');
?>
// Сертификат сохранен в файл signed_cert.crt

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

Создает новый запрос на подпись сертификата (CSR). Используется перед openssl_csr_sign для генерации исходного запроса.

openssl_x509_sign

Подписывает сертификат X.509 с помощью закрытого ключа. Может использоваться для прямой подписи данных сертификата без промежуточного CSR, но openssl_csr_sign предоставляет более высокоуровневый интерфейс для работы с CSR.

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

Неверный формат ключа
<?php
$csr = openssl_csr_new(['commonName' => 'test'], $priv_key);
// Передача строки вместо ресурса/объекта
$cert = openssl_csr_sign($csr, 'invalid_cert', 'invalid_key', 365);
?>
Warning: openssl_csr_sign(): supplied key param cannot be coerced into a private key
Истекший сертификат CA
<?php
// Попытка подписать CSR просроченным сертификатом CA
$cert = openssl_csr_sign($csr, $expired_ca_cert, $ca_key, 365);
?>
// Подпись может пройти, но клиенты не будут доверять такому сертификату

Изменения в PHP 8

В PHP 8.0 типы параметров $ca_cert и $private_key были расширены. Вместо ресурсов теперь используются объекты OpenSSLCertificate и OpenSSLAsymmetricKey. Передача ресурсов по-прежнему работает, но не рекомендуется. Аргумент $serial теперь может быть null, что приводит к генерации случайного серийного номера.

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

Использование конфигурационного файла и альтернативных алгоритмов
Пример php
<?php
$config = [
    'digest_alg' => 'sha512',
    'private_key_bits' => 4096,
];
$priv_key = openssl_pkey_new($config);
$csr = openssl_csr_new(['commonName' => 'secure.example.com'], $priv_key);

// Специальные опции для сертификата
$options = [
    'config' => '/usr/lib/ssl/openssl.cnf',
    'x509_extensions' => 'v3_req',
    'digest_alg' => 'sha512',
];
$cert = openssl_csr_sign($csr, null, $priv_key, 1825, $options, 0x1234ABCD);
?>
Создание цепочки сертификатов
Пример php
<?php
// Генерация корневого CA
$root_key = openssl_pkey_new(['private_key_bits' => 4096]);
$root_csr = openssl_csr_new(['commonName' => 'My Root CA'], $root_key);
$root_cert = openssl_csr_sign($root_csr, null, $root_key, 3650, ['x509_extensions' => 'v3_ca']);

// Генерация промежуточного CA, подписанного корневым
$inter_key = openssl_pkey_new(['private_key_bits' => 2048]);
$inter_csr = openssl_csr_new(['commonName' => 'My Intermediate CA'], $inter_key);
$inter_cert = openssl_csr_sign($inter_csr, $root_cert, $root_key, 1825, ['x509_extensions' => 'v3_ca']);

// Генерация конечного сертификата, подписанного промежуточным
$end_key = openssl_pkey_new(['private_key_bits' => 2048]);
$end_csr = openssl_csr_new(['commonName' => 'enduser.example.com'], $end_key);
$end_cert = openssl_csr_sign($end_csr, $inter_cert, $inter_key, 365);
?>
Обработка результата в виде массива
Пример php
<?php
$cert = openssl_csr_sign($csr, null, $priv_key, 365);
// Извлечение информации о сертификате
$info = openssl_x509_parse($cert);
print_r($info['subject']);
print_r($info['validTo_time_t']);
?>

Аналоги в других языках

Python (cryptography)
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import rsa
from cryptography.x509.oid import NameOID
import datetime

# Генерация ключа и CSR (упрощенно)
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
builder = x509.CertificateBuilder()
cert = builder.sign(private_key, hashes.SHA256())
# В отличие от PHP, процесс более объектно-ориентированный
JavaScript (Node.js с модулем crypto)
const crypto = require('crypto');
const { Certificate } = require('crypto');

// Создание CSR и подпись обычно выполняются через отдельные команды OpenSSL
// или с использованием сторонних библиотек, таких как 'pkijs'.
// Прямого аналога openssl_csr_sign в стандартном API нет.

PHP openssl_csr_sign function comments

En
Openssl csr sign Sign a CSR with another certificate (or itself) and generate a certificate