Openssl spki verify: примеры (PHP)
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
<?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.
Типичные ошибки
<?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
Функция openssl_spki_verify() была добавлена в PHP. Первоначальная реализация работала с базовой функциональностью проверки SPKAC.
Тип возвращаемого значения был ужесточен. Функция теперь всегда возвращает логическое значение true или false. В предыдущих версиях в некоторых случаях ошибки могло возвращаться null.
Функция поддерживает современные алгоритмы хеширования, доступные в OpenSSL. Совместимость с различными форматами PEM улучшена. Ошибки теперь более четко отделяют некорректные данные от сбоев проверки подписи.
Расширенные примеры использования
<?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 успешна Открытый ключ извлечен: да Вызов совпадает: да
<?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
// Предположим, что 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>Альтернативы в других языках
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())
# Проверка подписи выполняется другими методами
// Генерация пары ключей в браузере
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 предоставляет специализированную функцию для работы с форматом SPKAC, в то время как другие языки требуют реализации проверки подписи вручную или использования дополнительных библиотек. Формат SPKAC исторически связан с элементами браузера, поэтому в PHP реализована его прямая поддержка.