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

Проверка PKCS#7 подписей с помощью openssl_pkcs7_verify
Раздел: Шифрование (OpenSSL)
openssl_pkcs7_verify(string $input_filename, int $flags, ?string $signers_certificates_filename = null, array $ca_info = [], ?string $untrusted_certificates_filename = null, ?string $content = null, ?string $output_filename = null): bool|int

Функция openssl_pkcs7_verify

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

Функция openssl_pkcs7_verify() проверяет цифровую подпись сообщения формата PKCS#7 (S/MIME). Её применяют для верификации подлинности электронных документов, email-сообщений и данных, подписанных цифровыми сертификатами. Функция позволяет определить, не изменялись ли данные после подписания и действительна ли подпись.

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

Функция имеет следующий синтаксис:

openssl_pkcs7_verify(
    string $input_filename,
    int $flags,
    ?string $signers_certificates_filename = null,
    array $ca_info = [],
    ?string $untrusted_certificates_filename = null,
    ?string $content = null,
    ?string $output_filename = null
): bool|int

Описание параметров:

  1. input_filename – путь к файлу с подписанным сообщением PKCS#7.
  2. flags – флаги проверки. Могут быть комбинацией констант:
    • PKCS7_NOINTERN – не извлекать сертификаты подписанта.
    • PKCS7_NOVERIFY – не проверять цепочку сертификатов.
    • PKCS7_NOCHAIN – не проверять цепочку доверия.
    • PKCS7_NOSIGS – не проверять подписи.
    • PKCS7_NOATTR – игнорировать атрибуты подписи.
    • PKCS7_BINARY – не конвертировать данные в текст.
    • PKCS7_NOSMIMECAP – игнорировать атрибуты S/MIME.
    • PKCS7_NOCRL – не загружать CRL.
  3. signers_certificates_filename – файл для сохранения сертификатов подписантов.
  4. ca_info – массив доверенных сертификатов (CA).
  5. untrusted_certificates_filename – файл с дополнительными непроверенными сертификатами.
  6. content – исходное содержимое (если нужно сравнить).
  7. output_filename – файл для сохранения извлеченного содержимого.

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

Базовая проверка подписи
$inputFile = 'signed_message.p7m';
$result = openssl_pkcs7_verify($inputFile, 0);

if ($result === true) {
    echo 'Подпись действительна.';
} elseif ($result === false) {
    echo 'Ошибка проверки.';
} else {
    echo 'Некорректные данные.';
}
Подпись действительна.
Проверка с сохранением сертификатов
$flags = PKCS7_NOINTERN;
$certsFile = 'signers_certs.pem';
$result = openssl_pkcs7_verify('data.p7m', $flags, $certsFile);

if ($result && file_exists($certsFile)) {
    echo 'Сертификаты сохранены в ' . $certsFile;
}
Сертификаты сохранены в signers_certs.pem
Проверка с доверенными сертификатами
$caInfo = ['/path/to/ca_cert.pem'];
$result = openssl_pkcs7_verify('file.p7m', 0, null, $caInfo);

var_dump($result);
bool(true)

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

Функция проверяет цифровую подпись для исходных данных. Работает с сырыми подписями, а не с PKCS#7 контейнерами. Удобна для простых сценариев.

Расшифровывает данные PKCS#7. Используется, когда нужно извлечь содержимое зашифрованного сообщения.

openssl_cms_verify

Аналог для формата CMS (Cryptographic Message Syntax). Поддерживает современные стандарты, рекомендуется для новых проектов.

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

Некорректный путь к файлу
$result = openssl_pkcs7_verify('missing.p7m', 0);
var_dump($result);
bool(false) с предупреждением о невозможности открыть файл
Отсутствие расширения OpenSSL
if (!function_exists('openssl_pkcs7_verify')) {
    die('Расширение OpenSSL не загружено.');
}
Расширение OpenSSL не загружено.
Неверный формат данных
// Передача не-PKCS#7 данных
$result = openssl_pkcs7_verify('plain.txt', 0);
bool(false) или ошибка разбора

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

Строгая типизация

Аргументы функции стали строго типизированными. Передача неверных типов приводит к TypeError.

Нулевые значения по умолчанию

Параметры signers_certificates_filename, untrusted_certificates_filename, content, output_filename теперь допускают значение null по умолчанию.

Улучшенные сообщения об ошибках

Более подробная диагностика при сбоях проверки подписи.

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

Проверка нескольких подписей
Пример php
$flags = PKCS7_NOINTERN | PKCS7_NOVERIFY;
$certsFile = 'all_certs.pem';
$result = openssl_pkcs7_verify('multi_signed.p7m', $flags, $certsFile);

if ($result) {
    $certs = file_get_contents($certsFile);
    preg_match_all('/-----BEGIN CERTIFICATE-----.*?-----END CERTIFICATE-----/s', 
                   $certs, $matches);
    echo 'Найдено подписей: ' . count($matches[0]);
}
Найдено подписей: 3
Извлечение содержимого с проверкой
Пример php
$outputFile = 'extracted_content.txt';
$result = openssl_pkcs7_verify('signed.p7m', 0, null, [], null, null, $outputFile);

if ($result && file_exists($outputFile)) {
    echo 'Содержимое: ' . file_get_contents($outputFile);
}
Содержимое: Исходный текст сообщения.
Верификация с цепочкой доверия
Пример php
$caChain = ['root_ca.pem', 'intermediate_ca.pem'];
$result = openssl_pkcs7_verify('document.p7m', PKCS7_NOCHAIN, null, $caChain);

if ($result) {
    echo 'Цепочка сертификатов проверена.';
}
Цепочка сертификатов проверена.
Работа с S/MIME атрибутами
Пример php
$flags = PKCS7_NOSMIMECAP | PKCS7_NOATTR;
$result = openssl_pkcs7_verify('email.eml', $flags);
var_dump($result);
bool(true)

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

Python: cryptography.x509
from cryptography import x509
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding

with open('signed.p7m', 'rb') as f:
    data = f.read()
# Декодирование и проверка подписи
# (упрощенный пример)
Требуется дополнительная обработка PKCS#7
JavaScript: node-forge
const forge = require('node-forge');
const p7 = forge.pkcs7.messageFromPem(p7Data);
const verified = p7.verify();
console.log(verified);
true
MySQL: ASYMMETRIC_VERIFY
SELECT ASYMMETRIC_VERIFY('RSA-SHA256', 
    'original_data', 
    'signature', 
    'public_key');
1 (если подпись верна)

PHP openssl_pkcs7_verify function comments

En
Openssl pkcs7 verify Verifies the signature of an S/MIME signed message