Openssl public decrypt: примеры (PHP)

Расшифровка данных публичным ключом через openssl_public_decrypt
Раздел: Шифрование (OpenSSL)
openssl_public_decrypt(string $data, string &$decrypted_data, OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key, int $padding = OPENSSL_PKCS1_PADDING): bool

Функция openssl_public_decrypt

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

Аргументы функции
  • $data - строка с зашифрованными данными.
  • &$decrypted_data - переменная для сохранения результата расшифровки.
  • $public_key - публичный ключ в формате строки, ресурса или объекта OpenSSLAsymmetricKey (PHP 8.0+).
  • $padding - константа, определяющая режим заполнения: OPENSSL_PKCS1_PADDING (по умолчанию), OPENSSL_NO_PADDING, OPENSSL_PKCS1_OAEP_PADDING.

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

Базовое применение
$privateKey = openssl_pkey_new(['private_key_bits' => 2048]);
$publicKey = openssl_pkey_get_details($privateKey)['key'];

$data = 'Секретный текст';
openssl_private_encrypt($data, $encrypted, $privateKey);

$success = openssl_public_decrypt($encrypted, $decrypted, $publicKey);
echo $success ? $decrypted : 'Ошибка';
Секретный текст
Использование OAEP-заполнения
openssl_private_encrypt($data, $encrypted, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);
$result = openssl_public_decrypt($encrypted, $decrypted, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);
var_dump($result);
bool(true)

Альтернативные функции в PHP

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

Проверяет цифровую подпись данных. Используется для аутентификации без шифрования содержимого.

sodium_crypto_box_open

Библиотека Libsodium предлагает современные алгоритмы шифрования. Рекомендуется для новых проектов благодаря улучшенной безопасности.

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

Неверный формат ключа
$key = 'invalid_key';
$result = openssl_public_decrypt($encrypted, $decrypted, $key);
if ($result === false) {
    echo openssl_error_string();
}
error:0909006C:PEM routines:get_name:no start line
Несовпадение заполнения
openssl_private_encrypt($data, $encrypted, $privateKey);
$result = openssl_public_decrypt($encrypted, $decrypted, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);
var_dump($result);
bool(false)
Превышение размера данных

При использовании RSA размер данных для шифрования ограничен размером ключа. Для 2048-битного ключа максимум ~245 байт.

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

PHP 8.0

Тип параметра $public_key расширен с ресурса (resource) до объекта OpenSSLAsymmetricKey или строки. Функция теперь выбрасывает исключение при ошибках вместо генерации предупреждений.

PHP 7.0

Добавлена константа OPENSSL_PKCS1_OAEP_PADDING для улучшенной безопасности.

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

Обработка исключений в PHP 8+
Пример php
try {
    openssl_public_decrypt($encrypted, $decrypted, $publicKey);
    echo $decrypted;
} catch (\OpenSSLException $e) {
    echo 'Ошибка расшифровки: ' . $e->getMessage();
}
Работа с файлами ключей
Пример php
$publicKey = file_get_contents('/path/to/public_key.pem');
$key = openssl_pkey_get_public($publicKey);

if ($key === false) {
    die('Не удалось загрузить ключ');
}

$success = openssl_public_decrypt($encrypted, $decrypted, $key);
openssl_free_key($key);
Верификация подписи сообщения
Пример php
function verifySignature($data, $signature, $publicKey) {
    openssl_public_decrypt($signature, $decryptedHash, $publicKey);
    $actualHash = hash('sha256', $data, true);
    return hash_equals($decryptedHash, $actualHash);
}
Чтение сертификата X.509
Пример php
$cert = file_get_contents('certificate.crt');
$publicKey = openssl_pkey_get_public($cert);
$details = openssl_pkey_get_details($publicKey);

$success = openssl_public_decrypt($encrypted, $decrypted, $details['key']);
Пакетная обработка данных
Пример php
function decryptChunks($encryptedChunks, $publicKey) {
    $result = '';
    foreach ($encryptedChunks as $chunk) {
        if (openssl_public_decrypt($chunk, $decrypted, $publicKey)) {
            $result .= $decrypted;
        }
    }
    return $result;
}

Аналоги в других языках

Python (cryptography)
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding

with open("public_key.pem", "rb") as key_file:
    public_key = serialization.load_pem_public_key(key_file.read())

decrypted = public_key.decrypt(
    encrypted_data,
    padding.OAEP(mgf=padding.MGF1(hashes.SHA256()), hashes.SHA256(), None)
)
JavaScript (Web Crypto API)
async function publicDecrypt(publicKey, encrypted) {
    const decrypted = await window.crypto.subtle.decrypt(
        { name: "RSA-OAEP" },
        publicKey,
        encrypted
    );
    return new TextDecoder().decode(decrypted);
}
MySQL (asymmetric_decrypt)
SELECT ASYMMETRIC_DECRYPT('RSA_2048', encrypted_data, 'public_key_pem') 
AS decrypted;

PHP openssl_public_decrypt function comments

En
Openssl public decrypt Decrypts data with public key