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

Асимметричное шифрование в PHP: практическое применение openssl_public_encrypt
Раздел: Шифрование (OpenSSL)
openssl_public_encrypt(string $data, string &$encrypted_data, OpenSSLAsymmetricKey|OpenSSLCertificate|array|string $public_key, int $padding = OPENSSL_PKCS1_PADDING): bool

Функция openssl_public_encrypt

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

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

Аргументы функции
  • data (string) - исходные данные для шифрования. Максимальная длина зависит от выбранного алгоритма и режима дополнения.
  • encrypted_data (string) - переменная для получения результата шифрования в бинарном формате.
  • public_key (string|OpenSSLAsymmetricKey) - открытый ключ в формате PEM или ресурс ключа.
  • padding (int) - режим дополнения данных. Доступные константы: OPENSSL_PKCS1_PADDING (по умолчанию), OPENSSL_NO_PADDING, OPENSSL_PKCS1_OAEP_PADDING.

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

Базовое шифрование
$publicKey = openssl_pkey_get_public('-----BEGIN PUBLIC KEY----- ...');
$data = "Секретное сообщение";

if (openssl_public_encrypt($data, $encrypted, $publicKey)) {
    echo base64_encode($encrypted);
}
DdAbx3mK...9u4w==
Использование OAEP-дополнения
$result = openssl_public_encrypt(
    $data, 
    $encrypted, 
    $publicKey, 
    OPENSSL_PKCS1_OAEP_PADDING
);
true
Обработка неудачи
if (!openssl_public_encrypt($data, $encrypted, $invalidKey)) {
    echo openssl_error_string();
}
error:0909006C:PEM routines:get_name:no start line

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

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

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

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

Sodium Extension

Функции sodium_crypto_box_seal предоставляют современную криптографию с меньшей вероятностью ошибок. Рекомендуются для новых проектов.

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

Превышение размера данных
$data = str_repeat('a', 500);
openssl_public_encrypt($data, $encrypted, $publicKey);
Warning: openssl_public_encrypt(): data too large for key size
Некорректный формат ключа
$key = "not a key";
openssl_public_encrypt('test', $encrypted, $key);
false (с ошибкой в openssl_error_string())
Использование приватного ключа
$privateKey = openssl_pkey_get_private('-----BEGIN PRIVATE KEY-----...');
openssl_public_encrypt($data, $encrypted, $privateKey);
Warning: openssl_public_encrypt(): key parameter is not a valid public key
Потеря данных при бинарной передаче
$encrypted = openssl_public_encrypt($data, $encrypted, $publicKey);
echo $encrypted;
Может вывести нечитаемые символы или обрезать данные

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

PHP 8.0

Тип параметра public_key изменен с resource на OpenSSLAsymmetricKey. Функция теперь возвращает true при успехе вместо null.

PHP 7.0

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

PHP 5.6

Введена строгая проверка типов для параметра padding.

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

Шифрование с генерацией ключей
Пример php
$config = ['private_key_bits' => 2048];
$keyPair = openssl_pkey_new($config);
openssl_pkey_export($keyPair, $privateKey);
$publicKey = openssl_pkey_get_details($keyPair)['key'];

openssl_public_encrypt(
    'Данные для шифрования',
    $encrypted,
    $publicKey,
    OPENSSL_PKCS1_OAEP_PADDING
);

// Расшифровка
openssl_private_decrypt(
    $encrypted,
    $decrypted,
    $privateKey,
    OPENSSL_PKCS1_OAEP_PADDING
);
echo $decrypted;
Данные для шифрования
Потоковое шифрование больших данных
Пример php
function encryptLargeData($data, $publicKey) {
    $chunkSize = 200;
    $encryptedChunks = [];
    
    foreach (str_split($data, $chunkSize) as $chunk) {
        openssl_public_encrypt($chunk, $encrypted, $publicKey);
        $encryptedChunks[] = base64_encode($encrypted);
    }
    
    return implode('|', $encryptedChunks);
}
Работа с ключами в разных форматах
Пример php
// Из DER в PEM
$derKey = file_get_contents('public.der');
$pemKey = "-----BEGIN PUBLIC KEY-----\n" 
         . chunk_split(base64_encode($derKey)) 
         . "-----END PUBLIC KEY-----";

// Шифрование с ключом из файла
$key = file_get_contents('public.pem');
openssl_public_encrypt($data, $encrypted, $key);
Валидация перед шифрованием
Пример php
function safePublicEncrypt($data, $publicKey) {
    $keyDetails = openssl_pkey_get_details($publicKey);
    $maxLength = $keyDetails['bits'] / 8 - 42; // Для OAEP
    
    if (strlen($data) > $maxLength) {
        throw new Exception("Data exceeds maximum length");
    }
    
    return openssl_public_encrypt(
        $data, 
        $encrypted, 
        $publicKey, 
        OPENSSL_PKCS1_OAEP_PADDING
    );
}

Реализации в других языках

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

public_key = serialization.load_pem_public_key(pem_data)
ciphertext = public_key.encrypt(
    plaintext,
    padding.OAEP(
        mgf=padding.MGF1(hashes.SHA256()),
        algorithm=hashes.SHA256(),
        label=None
    )
)
JavaScript (WebCrypto API)
const publicKey = await crypto.subtle.importKey(
    'spki',
    pemToArrayBuffer(pem),
    { name: 'RSA-OAEP', hash: 'SHA-256' },
    false,
    ['encrypt']
);

const encrypted = await crypto.subtle.encrypt(
    { name: 'RSA-OAEP' },
    publicKey,
    new TextEncoder().encode(data)
);

Openssl public encrypt в MySQL

SELECT RSA_PUBLIC_ENCRYPT('secret',
    '-----BEGIN PUBLIC KEY-----...')
AS encrypted;

MySQL поддерживает только PKCS#1 v1.5, требует активного плагина MySQL Enterprise Edition.

PHP openssl_public_encrypt function comments

En
Openssl public encrypt Encrypts data with public key