Openssl spki verify: примеры (PHP)

Руководство по работе с openssl_spki_verify в PHP
Раздел: Шифрование (OpenSSL)
openssl_spki_verify(string $spki): bool

Функция openssl_spki_verify в PHP

Описание и назначение

Функция openssl_spki_verify() выполняет проверку подписанного открытого ключа с вызовом (Signed Public Key and Challenge, SPKAC). Она используется для верификации данных, сгенерированных элементом HTML <keygen> или через функцию openssl_spki_new(). Проверка подтверждает целостность и подлинность структуры SPKAC.

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

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

  • $spki (string) - строка, содержащая подписанный открытый ключ с вызовом в формате PEM. Обычно начинается с -----BEGIN SPKAC-----.

Функция возвращает логическое значение:

  • true - если подпись SPKAC корректна.
  • false - при неудачной проверке или ошибке.

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

Базовая проверка валидного SPKAC
<?php
// Создание SPKAC
$config = ['digest_alg' => 'sha256', 'private_key_bits' => 2048];
$privateKey = openssl_pkey_new($config);
$spkac = openssl_spki_new($privateKey, 'challenge123');

// Проверка созданного SPKAC
$result = openssl_spki_verify($spkac);
echo 'Результат проверки: ' . ($result ? 'true' : 'false');
?>
Результат проверки: true
Проверка некорректных данных
<?php
// Передача поврежденной строки SPKAC
$invalidSpkac = '-----BEGIN SPKAC-----\nInvalidData\n-----END SPKAC-----';
$result = openssl_spki_verify($invalidSpkac);
var_dump($result);

// Передача обычной строки
$result2 = openssl_spki_verify('not a spkac string');
var_dump($result2);
?>
bool(false)
bool(false)

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

Создает новый SPKAC, подписывая открытый ключ с вызовом. Используется для генерации данных перед их проверкой через openssl_spki_verify().

Извлекает открытый ключ в формате PEM из структуры SPKAC. Применяется для получения ключа после успешной проверки.

Извлекает вызов (challenge) из структуры SPKAC. Полезно для получения исходного вызова после проверки подписи.

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

openssl_spki_verify используется исключительно для проверки целостности существующих данных SPKAC. Для создания новых данных применяется openssl_spki_new, а для извлечения компонентов - openssl_spki_export и openssl_spki_export_challenge.

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

Некорректный формат строки SPKAC
<?php
// Отсутствуют границы PEM формата
$spkacWithoutBoundaries = 'MIIB...';
$result = openssl_spki_verify($spkacWithoutBoundaries);
var_dump($result); // false
?>
bool(false)
Использование результата как строки
<?php
$privateKey = openssl_pkey_new(['private_key_bits' => 1024]);
$spkac = openssl_spki_new($privateKey, 'test');
$result = openssl_spki_verify($spkac);

// Неправильное использование результата
if ($result == 'true') { // Ложное сравнение
    echo 'Проверка пройдена';
}
// Правильно:
if ($result === true) {
    echo 'Проверка пройдена';
}
?>
Попытка проверки модифицированных данных
<?php
$privateKey = openssl_pkey_new(['private_key_bits' => 1024]);
$spkac = openssl_spki_new($privateKey, 'original');

// Изменение строки SPKAC
$modifiedSpkac = str_replace('original', 'modified', $spkac);
$result = openssl_spki_verify($modifiedSpkac);
var_dump($result);
?>
bool(false)

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

PHP 5.6.0

Функция openssl_spki_verify() была добавлена в PHP. Первоначальная реализация работала с базовой функциональностью проверки SPKAC.

PHP 8.0.0

Тип возвращаемого значения был ужесточен. Функция теперь всегда возвращает логическое значение true или false. В предыдущих версиях в некоторых случаях ошибки могло возвращаться null.

Текущая версия PHP 8.x

Функция поддерживает современные алгоритмы хеширования, доступные в OpenSSL. Совместимость с различными форматами PEM улучшена. Ошибки теперь более четко отделяют некорректные данные от сбоев проверки подписи.

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

Полный цикл генерации и проверки
Пример php
<?php
// Конфигурация ключа
$config = [
    'digest_alg' => 'sha512',
    'private_key_bits' => 4096,
    'private_key_type' => OPENSSL_KEYTYPE_RSA
];

// Генерация приватного ключа
$privateKey = openssl_pkey_new($config);

// Создание SPKAC с вызовом
$challenge = bin2hex(random_bytes(16));
$spkac = openssl_spki_new($privateKey, $challenge);

echo 'Создан SPKAC длиной: ' . strlen($spkac) . ' байт<br>';

// Проверка SPKAC
if (openssl_spki_verify($spkac)) {
    echo 'Проверка SPKAC успешна<br>';
    
    // Извлечение открытого ключа
    $publicKey = openssl_spki_export($spkac);
    echo 'Открытый ключ извлечен: ' . (strlen($publicKey) > 0 ? 'да' : 'нет') . '<br>';
    
    // Извлечение вызова
    $extractedChallenge = openssl_spki_export_challenge($spkac);
    echo 'Вызов совпадает: ' . ($extractedChallenge === $challenge ? 'да' : 'нет') . '<br>';
} else {
    echo 'Проверка SPKAC не удалась';
}
?>
Создан SPKAC длиной: 1862 байт
Проверка SPKAC успешна
Открытый ключ извлечен: да
Вызов совпадает: да
Пакетная проверка нескольких SPKAC
Пример php
<?php
function verifySpkacArray(array $spkacArray): array {
    $results = [];
    
    foreach ($spkacArray as $index => $spkac) {
        $results[$index] = [
            'valid' => openssl_spki_verify($spkac),
            'length' => strlen($spkac),
            'challenge' => openssl_spki_verify($spkac) ? 
                openssl_spki_export_challenge($spkac) : null
        ];
    }
    
    return $results;
}

// Пример массива SPKAC (в реальности заполняется данными)
$testData = [
    'user1' => '-----BEGIN SPKAC-----\nMIIC...\n-----END SPKAC-----',
    'user2' => '-----BEGIN SPKAC-----\nMIID...\n-----END SPKAC-----'
];

$results = verifySpkacArray($testData);
print_r($results);
?>
Интеграция с веб-формой
Пример php
<?php
// Предположим, что SPKAC получен из формы
$submittedSpkac = $_POST['spkac'] ?? '';

if (!empty($submittedSpkac)) {
    // Очистка и проверка
    $spkac = preg_replace('/\\s+/', '', $submittedSpkac);
    
    // Добавление границ PEM, если отсутствуют
    if (strpos($spkac, '-----BEGIN SPKAC-----') === false) {
        $spkac = "-----BEGIN SPKAC-----\n" . 
                chunk_split($spkac, 64, "\n") . 
                "-----END SPKAC-----";
    }
    
    $isValid = openssl_spki_verify($spkac);
    
    if ($isValid) {
        $publicKey = openssl_spki_export($spkac);
        // Сохранение ключа в базу данных или файл
        file_put_contents('public_key.pem', $publicKey);
        echo 'Ключ успешно проверен и сохранен';
    } else {
        echo 'Ошибка проверки SPKAC';
    }
}
?>

<!-- HTML форма для генерации SPKAC в браузере -->
<form method="post">
    <keygen name="spkac" challenge="random123">
    <input type="submit" value="Отправить ключ">
</form>

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

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

# В Python нет прямой аналогии, используется проверка подписи
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
public_key = private_key.public_key()

# Экспорт открытого ключа в PEM
pem = public_key.public_bytes(
    encoding=serialization.Encoding.PEM,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
print(pem.decode())
# Проверка подписи выполняется другими методами
JavaScript (Web Crypto API)
// Генерация пары ключей в браузере
window.crypto.subtle.generateKey(
    {
        name: "RSASSA-PKCS1-v1_5",
        modulusLength: 2048,
        publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
        hash: {name: "SHA-256"}
    },
    true,
    ["sign", "verify"]
)
.then(keyPair => {
    // Экспорт открытого ключа
    return window.crypto.subtle.exportKey("spki", keyPair.publicKey);
})
.then(spki => {
    console.log(new Uint8Array(spki));
});
// Прямой аналогии openssl_spki_verify в JavaScript нет
Отличия от PHP

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

PHP openssl_spki_verify function comments

En
Openssl spki verify Verifies a signed public key and challenge