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

Практическое руководство по использованию openssl_sign в PHP
Раздел: Шифрование (OpenSSL)
openssl_sign(string $data, string &$signature, OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $private_key, string|int $algorithm = OPENSSL_ALGO_SHA1): bool
Функция openssl_sign

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

Аргументы функции
  • data (string) - исходные данные, для которых создается подпись.
  • signature (string) - переменная, передаваемая по ссылке, в которую будет записана сгенерированная подпись в бинарном формате.
  • private_key (mixed) - приватный ключ в виде строки (PEM-формат) или ресурса. Может быть также массивом с данными ключа.
  • algorithm (int|string) - алгоритм хеширования. Можно передавать как константу (OPENSSL_ALGO_SHA256 и др.), так и строковое имя ('SHA256').

Функция возвращает true в случае успеха и false при возникновении ошибки.

Краткие примеры
Простая подпись строки

Создание подписи с использованием SHA256.

<?php
$data = "Важные данные для подписи";
$private_key = openssl_pkey_get_private("file://path/to/private.key");
$success = openssl_sign($data, $signature, $private_key, OPENSSL_ALGO_SHA256);
if ($success) {
    echo "Подпись создана.";
}
?>
Подпись создана.
Использование строкового имени алгоритма
<?php
$data = "Тест";
$key = openssl_pkey_get_private("file://key.pem");
$result = openssl_sign($data, $sig, $key, "sha512");
var_dump($result);
?>
bool(true)
Похожие функции в PHP

openssl_verify - функция для проверки цифровой подписи. Используется вместе с openssl_sign. Принимает данные, подпись и открытый ключ.

hash_hmac - создает хеш с ключом на основе алгоритма HMAC. Применяется для проверки целостности данных, но не для цифровой подписи в асимметричной криптографии.

sodium_crypto_sign_detached - функция из модуля Sodium для создания отделенной подписи. Обычно более быстрая и рекомендуется в современных версиях PHP для новых проектов.

Выбор функции зависит от задачи: openssl_sign и openssl_verify используются для асимметричной подписи, hash_hmac - для симметричной проверки целостности, sodium_crypto_sign_detached - для современных криптографических решений.

Типичные ошибки
Неверный формат или тип приватного ключа
<?php
$data = "test";
$bad_key = "not a key";
var_dump(openssl_sign($data, $signature, $bad_key, OPENSSL_ALGO_SHA256));
?>
bool(false)
Неподдерживаемый алгоритм хеширования
<?php
$key = openssl_pkey_new();
var_dump(openssl_sign("data", $sig, $key, "UNKNOWN_ALGO"));
?>
Warning: openssl_sign(): Unknown signature algorithm.
bool(false)
Передача данных не в виде строки
<?php
$key = openssl_pkey_new();
$array_data = ["data"];
var_dump(openssl_sign($array_data, $sig, $key, OPENSSL_ALGO_SHA256));
?>
Warning: openssl_sign() expects parameter 1 to be string, array given.
NULL
Изменения в новых версиях PHP

В PHP 8.0 параметр private_key теперь принимает также экземпляр OpenSSLAsymmetricKey или OpenSSLCertificate, а ресурсы (resource) объявлены устаревшими.

В PHP 8.1 добавлена поддержка алгоритма RSASSA-PSS через константу OPENSSL_ALGO_SHA256 и др. с суффиксом -PSS (например, OPENSSL_ALGO_SHA256).

С PHP 8.0 некоторые криптографические функции, включая openssl_sign, выбрасывают исключения в случае ошибок вместо генерации предупреждений, если не используется оператор @.

Расширенные примеры
Подпись сериализованного массива с проверкой
Пример php
<?php
$dataArray = ["user_id" => 123, "action" => "login", "timestamp" => time()];
$dataSerialized = serialize($dataArray);

$config = ["digest_alg" => "sha512", "private_key_bits" => 2048];
$keyPair = openssl_pkey_new($config);
openssl_pkey_export($keyPair, $privateKeyPem);
$publicKeyDetails = openssl_pkey_get_details($keyPair);
$publicKeyPem = $publicKeyDetails["key"];

if (openssl_sign($dataSerialized, $signature, $privateKeyPem, OPENSSL_ALGO_SHA512)) {
    $signatureBase64 = base64_encode($signature);
    echo "Подпись (Base64): " . $signatureBase64 . "<br>";
    $verification = openssl_verify($dataSerialized, $signature, $publicKeyPem, OPENSSL_ALGO_SHA512);
    echo "Результат проверки: ";
    var_dump($verification); // 1 - успешно
}
?>
Подпись (Base64): OTViMjA0YzY... (обрезано)
Результат проверки: int(1)
Использование массива с данными ключа
Пример php
<?php
$keyData = [
    "digest_alg" => "sha256",
    "private_key_type" => OPENSSL_KEYTYPE_RSA,
    "private_key_bits" => 1024
];
$keyResource = openssl_pkey_new($keyData);
$data = "Конфиденциальная информация";
$success = openssl_sign($data, $sig, $keyResource, "sha256");
if ($success) {
    echo "Подпись сгенерирована через массив параметров ключа.";
}
?>
Подпись сгенерирована через массив параметров ключа.
Подпись с алгоритмом RSASSA-PSS (PHP 8.1+)
Пример php
<?php
$key = openssl_pkey_new(["private_key_bits" => 2048]);
$data = "Данные для PSS";
if (defined('OPENSSL_ALGO_SHA256')) {
    $algo = OPENSSL_ALGO_SHA256; // Используется PSS
    if (openssl_sign($data, $signature, $key, $algo)) {
        echo "Подпись PSS создана.";
    }
}
?>
Подпись PSS создана.
Альтернативы в других языках
Python (cryptography)
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding, rsa
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
data = b"data to sign"
signature = private_key.sign(data, padding.PKCS1v15(), hashes.SHA256())
print(signature.hex())
JavaScript (Web Crypto API)
async function signData(privateKeyJwk, data) {
    const key = await crypto.subtle.importKey('jwk', privateKeyJwk, { name: 'RSASSA-PKCS1-v1_5', hash: 'SHA-256' }, false, ['sign']);
    const signature = await crypto.subtle.sign('RSASSA-PKCS1-v1_5', key, new TextEncoder().encode(data));
    return Array.from(new Uint8Array(signature)).map(b => b.toString(16).padStart(2, '0')).join('');
}

Openssl sign в MySQL

Прямого аналога нет. Подобные операции обычно выполняются на уровне приложения.

Основные отличия: в Python и JS часто используются объектно-ориентированные интерфейсы, а в PHP функция procedural. Также отличаются способы представления ключей.

PHP openssl_sign function comments

En
Openssl sign Generate signature