проверка openssl и "ошибка: 0906D06C: процедуры PEM: PEM чтение биографии: нет начальной строки"
Я пытаюсь использовать функцию OpenSSL для подписи/проверки RSA в PHP.
Когда я пытаюсь сделать openssl_verify
, используя свой открытый ключ, я получаю эту ошибку: error:0906D06C:PEM routines:PEM_read_bio:no start line
, но сама функция работает правильно (возвращает 0, если сообщения были изменены, и 1, если нетронуты). openssl_sign
работает нормально.
Как я могу это исправить?
В настоящее время я использую открытый ключ, сгенерированный openssl:
define("SC_MSG_PUBLIC", <<<EOD
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALjPcOckMHDVLiUstcRwwx8kF5PzsiEs
rskyndWisbXMLU9BHomXwL7Qg2L91jE+sNSobkzBDF41CbwDiNlofZUCAwEAAQ==
-----END PUBLIC KEY-----
EOD
);
Есть идеи, почему возникает эта ошибка, но все работает нормально?
Попытался сгенерировать открытый ключ из личного доступа и используйте его, но оно оказалось точно таким же, то же сообщение об ошибке:-S
$pkey = openssl_pkey_get_private(SC_MSG_PRIVATE);
$keyDetails = openssl_pkey_get_details($pkey);
file_put_contents('c:\publickey', $keyDetails['key']);
Кроме того, я пытался установить более новые версии всего (PHP 5.3.1, OpenSSL 1.0.0a) - тот же результат. И я нахожусь в Windows.
4 answers
Вы пытались вызвать openssl_verify() с помощью (возможно, самозаверяющего) сертификата, содержащего ваш открытый ключ вместо чистого открытого ключа?
Насколько я знаю, некоторые функции PHP OpenSSL не поддерживают должным образом открытые открытые ключи, хотя кажется странным, что он правильно проверяет, несмотря на ошибку.
<?php
$private = openssl_pkey_get_private(file_get_contents('private'), 'passphrase');
// This causes the "no start line" error when using a naked public key:
$public = openssl_pkey_get_public(file_get_contents('public')); // <-- this should be cert
echo openssl_error_string()."\n";
openssl_sign('Test', $sig, $private);
var_dump(openssl_verify('Test', $sig, $public));
echo openssl_error_string()."\n";
?>
Пример преобразования открытого ключа в простой сертификат в оболочке Linux/UNIX, такой как bash (см. документацию OpenSSL или некоторые учебные пособия для получения дополнительной информации):
# Create certificate request
openssl req -new -days 3600 -key [PRIVATE-KEY-FILE] -out [REQUEST-TMP-FILE]
# Create certificate from request
RANDFILE=[RANDOM-TMP-FILE] openssl x509 -req -in [REQUEST-TMP-FILE] -signkey [PRIVATE-KEY-FILE] -out [CERTIFICATE-OUT-FILE]
Это также создаст временные файлы, которые вы, возможно, захотите удалить впоследствии, а именно[ФАЙЛ ЗАПРОСА TMP] и [СЛУЧАЙНЫЙ ФАЙЛ TMP].
Пример кода PHP можно найти по адресу http://de.php.net/manual/en/function.openssl-csr-new.php.
Там, где у всех остальных есть errno, который автоматически сбрасывается до нуля при успешных операциях, в OpenSSL есть "стек ошибок", который вам нужно очистить вручную. Смотрите функцию openssl_error_string, которая реализована в терминах ERR_get_error. Скорее всего, сообщение об ошибке, которое вы видите, не имеет никакого отношения к вашему коду; попробуйте добавить это перед вашим кодом:
while ($msg = openssl_error_string()) {};
И между каждой строкой:
while ($msg = openssl_error_string())
echo "OpenSSL error when doing foo:" . $msg . "<br />\n";
Возможно, вам будет проще использовать phpseclib для создания/проверки подписи:
Http://phpseclib.sourceforge.net/documentation/misc_crypt.html#misc_crypt_rsa_examples
Причина:
Эта ошибка обычно вызвана одним поврежденным символом в начале файла .crt. Таким образом, есть вероятность, что у вас есть лишний пробел, дополнительный символ, дополнительная строка и т.д. Либо в файле сертификата SSL (.crt), либо в файле ключа SSL (.key).
Возможные решения:
- Проверьте свой файл .crt.
- Проблема с персонажем может быть в вашем ключе, попробуйте это (без разрывов строк и т. Д.):
.
define("SC_MSG_PUBLIC", "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALjPcOckMHDVLiUstcRwwx8kF5PzsiEsrskyndWisbXMLU9BHomXwL7Qg2L91jE+sNSobkzBDF41CbwDiNlofZUCAwEAAQ==");