Openssl verify: примеры (PHP)
Проверка цифровых подписей с помощью openssl_verify
Раздел: Шифрование (OpenSSL)
openssl_verify(string $data, string $signature, OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key, string|int $algorithm = OPENSSL_ALGO_SHA1): int|falseОписание функции openssl_verify
Функция openssl_verify выполняет проверку цифровой подписи для данных. Она используется в сценариях, требующих подтверждения целостности и аутентичности информации, например, при обработке платежных уведомлений, проверке сертификатов или защищенном обмене данными между системами.
Аргументы функции
- $data (string) - строковые данные, для которых создавалась подпись. Обычно это хэш (дайджест) исходных данных, но может быть и сами данные.
- $signature (string) - сырая двоичная строка или строка в кодировке base64, содержащая подпись.
- $public_key (OpenSSLAsymmetricKey|OpenSSLCertificate|string) - открытый ключ или сертификат X.509 в формате PEM или строке, используемый для проверки.
- $algorithm (int|string) - алгоритм хэширования. В PHP 8 может быть строкой (напр., "sha256WithRSAEncryption") или константой (напр.,
OPENSSL_ALGO_SHA256). - flags (int) - опциональный параметр, влияющий на поведение проверки. Основные флаги:
OPENSSL_ALGO_SHA256(и другие алгоритмы),OPENSSL_PKCS1_PADDING(по умолчанию для RSA),OPENSSL_NO_PADDING(без дополнения).
Функция возвращает 1 при успешной проверке, 0 при неудаче и -1 в случае ошибки.
Короткие примеры использования
Пример 1: Базовая проверка с RSA ключом
// Генерация ключей
$config = [
"private_key_bits" => 2048,
];
$keyPair = openssl_pkey_new($config);
openssl_pkey_export($keyPair, $privateKeyPem);
$publicKeyDetails = openssl_pkey_get_details($keyPair);
$publicKeyPem = $publicKeyDetails['key'];
// Данные и подпись
$data = "Важные данные для подписи";
openssl_sign($data, $signature, $privateKeyPem, OPENSSL_ALGO_SHA256);
// Проверка подписи
$result = openssl_verify($data, $signature, $publicKeyPem, OPENSSL_ALGO_SHA256);
echo "Результат проверки: $result\n"; // 1Результат проверки: 1
Пример 2: Проверка с флагом OPENSSL_PKCS1_PADDING
$result = openssl_verify($data, $signature, $publicKeyPem, OPENSSL_ALGO_SHA256 | OPENSSL_PKCS1_PADDING);
echo "Результат с PKCS1: $result\n";Результат с PKCS1: 1
Пример 3: Неверная подпись
$wrongSignature = str_repeat('0', 64); // Некорректная подпись
$result = openssl_verify($data, $wrongSignature, $publicKeyPem, OPENSSL_ALGO_SHA256);
echo "Результат с неверной подписью: $result\n";Результат с неверной подписью: 0
Похожие функции в PHP
- openssl_sign - создает цифровую подпись. Используется вместе с openssl_verify для полного цикла подписи и проверки.
- openssl_pkey_verify - альтернативная функция для проверки подписи, принимающая данные в виде массива. Более гибкая для работы с различными форматами данных.
- hash_hmac_verify - проверяет подпись HMAC, что подходит для симметричного шифрования. Работает быстрее, но требует общего секретного ключа.
Для асимметричной криптографии предпочтительнее openssl_verify, а для симметричной - hash_hmac_verify.
Типичные ошибки
Ошибка 1: Некорректный формат ключа
$wrongKey = "not a key";
$result = openssl_verify($data, $signature, $wrongKey, OPENSSL_ALGO_SHA256);
var_dump($result); // -1int(-1)
Ошибка 2: Несоответствие алгоритмов
// Подпись создана с SHA256, а проверка с SHA1
$result = openssl_verify($data, $signature, $publicKeyPem, OPENSSL_ALGO_SHA1);
echo "Результат с неверным алгоритмом: $result\n";Результат с неверным алгоритмом: 0
Ошибка 3: Передача данных в неверном формате
// Подпись в base64 без декодирования
$signatureBase64 = base64_encode($signature);
$result = openssl_verify($data, $signatureBase64, $publicKeyPem, OPENSSL_ALGO_SHA256);
echo "Результат с base64 без декодирования: $result\n";Результат с base64 без декодирования: 0
Изменения в последних версиях PHP
- В PHP 8.0 параметр
$public_keyтеперь принимает объектыOpenSSLAsymmetricKeyилиOpenSSLCertificateвместо ресурсов (resource). Аргумент$algorithmможет быть строкой. - В PHP 7.2 добавлена возможность использовать строковые имена алгоритмов (например, "sha256WithRSAEncryption") для параметра
$algorithm. - С PHP 8.1 функция возвращает false при недопустимых значениях аргументов, что улучшает строгость типизации.
Расширенные примеры использования
Пример 1: Проверка подписи с сертификатом X.509
Пример php
// Загрузка сертификата
$certificate = file_get_contents('certificate.pem');
$data = file_get_contents('signed_data.txt');
$signature = file_get_contents('signature.bin');
$result = openssl_verify($data, $signature, $certificate, OPENSSL_ALGO_SHA384);
if ($result === 1) {
echo "Подпись сертификата действительна.";
} elseif ($result === 0) {
echo "Подпись недействительна.";
} else {
echo "Ошибка при проверке: " . openssl_error_string();
}Подпись сертификата действительна.
Пример 2: Проверка подписи для хэшированных данных
Пример php
// Иногда подпись создается для хэша данных
$rawData = "Исходные данные";
$hash = hash('sha256', $rawData, true); // true - сырой двоичный вывод
// Предположим, что $signature создана для $hash
$result = openssl_verify($hash, $signature, $publicKeyPem, OPENSSL_ALGO_SHA256);
// Важно: алгоритм должен соответствовать тому, что использовался для хэшированияПример 3: Обработка нескольких подписей для одних данных
Пример php
$signatures = [
'signature1.bin',
'signature2.bin'
];
$validSignatures = [];
foreach ($signatures as $sigFile) {
$sig = file_get_contents($sigFile);
if (openssl_verify($data, $sig, $publicKeyPem, OPENSSL_ALGO_SHA256) === 1) {
$validSignatures[] = $sigFile;
}
}
print_r($validSignatures);Array
(
[0] => signature1.bin
)Пример 4: Использование строкового имени алгоритма
Пример php
$result = openssl_verify(
$data,
$signature,
$publicKeyPem,
"sha512WithRSAEncryption"
);
echo "Результат со строковым алгоритмом: $result\n";Результат со строковым алгоритмом: 1
Аналоги в других языках
Python (cryptography)
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.exceptions import InvalidSignature
public_key.verify(
signature,
data,
padding.PKCS1v15(),
hashes.SHA256()
) # Выбрасывает исключение при ошибкеJavaScript (Node.js crypto)
const crypto = require('crypto');
const verify = crypto.createVerify('SHA256');
verify.update(data);
verify.end();
const isValid = verify.verify(publicKey, signature, 'base64');
// isValid - true/falseMySQL (асимметричное шифрование)
В MySQL нет прямой аналогии для проверки подписи, но есть функции асимметричного шифрования, например, ASYMMETRIC_VERIFY() (доступна в MariaDB).
PHP openssl_verify function comments
En
Openssl verify Verify signature