Openssl error string: примеры (PHP)
openssl_error_string: string|falseОсновные сведения о функции openssl_error_string
Функция openssl_error_string() возвращает текстовое описание последней ошибки, произошедшей в расширении OpenSSL. Эта функция не принимает параметров и вызывается после неудачных операций с криптографическими алгоритмами.
Использование функции актуально при выполнении операций шифрования, расшифровки, подписи и проверки подписей, генерации ключей, работы с сертификатами X.509. Функция помогает в отладке, предоставляя человекочитаемые сообщения об ошибках из библиотеки OpenSSL.
Возвращает строку с описанием ошибки или false, если в стеке ошибок OpenSSL больше нет сообщений. Для получения всех ошибок необходимо вызывать функцию в цикле до получения значения false.
Каждый вызов функции возвращает следующую ошибку из стека и удаляет ее оттуда. Стек ошибок очищается при успешных операциях. Сообщения об ошибках накапливаются только при неудачных вызовах функций OpenSSL.
Простые примеры использования
<?php
// Пытаемся расшифровать данные с неправильным ключом
$data = 'зашифрованные данные';
$key = 'неверный ключ';
$method = 'AES-256-CBC';
$result = openssl_decrypt($data, $method, $key);
if ($result === false) {
$error = openssl_error_string();
echo "Ошибка: $error";
}
?>Ошибка: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
<?php
// Выполняем несколько операций с ошибками
openssl_pkey_get_private('invalid_key');
openssl_sign('data', $signature, 'wrong_key', OPENSSL_ALGO_SHA256);
// Получаем все ошибки
while ($errorMsg = openssl_error_string()) {
echo "$errorMsg\n";
}
?>error:0909006C:PEM routines:get_name:no start line error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
Альтернативные функции в PHP
Функция возвращает массив всех ошибок из стека OpenSSL без их удаления. Полезно для логирования всех ошибок перед очисткой стека.
<?php
openssl_pkey_get_public('invalid');
$errors = openssl_get_errors();
print_r($errors);
?>Array
(
[0] => error:0909006C:PEM routines:get_name:no start line
)Можно создавать пользовательские исключения с сообщениями об ошибках OpenSSL для более структурированной обработки.
<?php
function decryptData($data, $key) {
$result = openssl_decrypt($data, 'AES-256-CBC', $key);
if ($result === false) {
throw new Exception('Ошибка расшифровки: ' . openssl_error_string());
}
return $result;
}
?>Распространенные ошибки
<?php
// Неправильно: вызов без предшествующей операции OpenSSL
$error = openssl_error_string();
echo $error ?: "Нет ошибок";
?>Нет ошибок
<?php
// Опасный код: false может быть интерпретировано как строка
$error = openssl_error_string();
if ($error) { // false преобразуется в пустую строку
echo "Ошибка: $error";
}
// Лучше использовать строгое сравнение
if ($error !== false) {
echo "Ошибка: $error";
}
?><?php
openssl_encrypt('data', 'unknown_cipher', 'key');
// Получаем первую ошибку
$error1 = openssl_error_string();
// Получаем вторую ошибку (если есть)
$error2 = openssl_error_string();
// Если была только одна ошибка, $error2 будет false
?>Изменения в новых версиях PHP
В PHP 8 улучшена обработка ошибок OpenSSL. Некоторые функции теперь выбрасывают исключения вместо молчаливого возврата false. Однако openssl_error_string() сохраняет обратную совместимость и продолжает работать.
С версии PHP 7.4 улучшена очистка стека ошибок. Теперь при успешных операциях стек очищается более предсказуемо. В ранних версиях могли оставаться устаревшие сообщения об ошибках.
В современном коде рекомендуется использовать механизм исключений в сочетании с openssl_error_string() для получения детальной информации:
<?php
try {
$key = openssl_pkey_get_private('invalid_key');
if ($key === false) {
throw new RuntimeException('Ошибка ключа: ' . openssl_error_string());
}
} catch (Exception $e) {
echo $e->getMessage();
}
?>Расширенные примеры применения
<?php
class OpenSSLDebugger {
private static $errors = [];
public static function executeWithLogging(callable $opensslOperation) {
$result = $opensslOperation();
if ($result === false) {
while ($error = openssl_error_string()) {
self::$errors[] = [
'time' => date('Y-m-d H:i:s'),
'message' => $error
];
}
}
return $result;
}
public static function getErrors() {
return self::$errors;
}
}
// Использование
$data = 'test';
$encrypted = OpenSSLDebugger::executeWithLogging(
fn() => openssl_encrypt($data, 'AES-256-CBC', 'key', 0, 'iv')
);
print_r(OpenSSLDebugger::getErrors());
?><?php
function categorizeOpenSSLError($errorString) {
$patterns = [
'bad_decrypt' => '/bad decrypt/i',
'key_error' => '/key.*error|password.*wrong/i',
'format_error' => '/PEM routines|bad base64/i',
'algorithm_error' => '/algorithm.*not found/i'
];
foreach ($patterns as $category => $pattern) {
if (preg_match($pattern, $errorString)) {
return $category;
}
}
return 'unknown';
}
// Тестирование
openssl_decrypt('data', 'AES-256-CBC', 'wrong_key');
$error = openssl_error_string();
$category = categorizeOpenSSLError($error);
echo "Категория ошибки: $category\n";
echo "Текст ошибки: $error";
?>Категория ошибки: bad_decrypt Текст ошибки: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
<?php
function tryMultipleDecryptions($encryptedData, $possibleKeys) {
foreach ($possibleKeys as $key) {
$result = openssl_decrypt(
$encryptedData,
'AES-256-CBC',
$key,
OPENSSL_RAW_DATA,
'initialization_vector'
);
if ($result !== false) {
return $result;
}
// Логируем ошибку для этого ключа
$error = openssl_error_string();
error_log("Не удалось расшифровать с ключом: $key. Ошибка: $error");
}
return false;
}
$keys = ['key1', 'key2', 'correct_key'];
$decrypted = tryMultipleDecryptions($encryptedData, $keys);
?>Аналоги в других языках программирования
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
try:
public_key.verify(
signature,
data,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH
),
hashes.SHA256()
)
except InvalidSignature as e:
print(f"Ошибка проверки подписи: {e}")const crypto = require('crypto');
try {
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
} catch (error) {
console.error(`Ошибка расшифровки: ${error.message}`);
}MySQL возвращает NULL или сообщения об ошибках через механизм исключений СУБД, а не через отдельную функцию получения ошибок.
SELECT AES_DECRYPT('invalid_data', 'key');
-- Результат: NULL с установленным предупреждением