Я пытаюсь подписать файл, используя openssl_sign()
функция. У меня есть следующий закрытый ключ:
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDzQVg9bJ1kZFsZDoLeqadA4OTgKc40ukSmQ3MVzcV0soAcGBSuBBAAK
oUQDQgAEvzUNKCE3UVimCLUePomOUH/kfy0ujHdN5Kmn7ez3TtokJDy5ksVnOgf6
WzpmzY46zvKAnQ44Cgx5Kdqx5dVDiw==
-----END EC PRIVATE KEY-----
Я использую следующую функцию: openssl_sign("test", $signature, $private_key, OPENSSL_ALGO_SHA256);
,
У меня есть один сервер, который может подписать, используя данный ключ, и один, который не может. Тот, который имеет PHP 5.6, а тот, который не имеет PHP 7.1. Почему один сервер может использовать ключ, а другой нет?
Возможно, вам нужно использовать openssl_get_privatekey
создать ресурс закрытого ключа, а не просто использовать строку
$str_priv_key='-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIDzQVg9bJ1kZFsZDoLeqadA4OTgKc40ukSmQ3MVzcV0soAcGBSuBBAAK
oUQDQgAEvzUNKCE3UVimCLUePomOUH/kfy0ujHdN5Kmn7ez3TtokJDy5ksVnOgf6
WzpmzY46zvKAnQ44Cgx5Kdqx5dVDiw==
-----END EC PRIVATE KEY-----';
$pkey=openssl_get_privatekey( $str_priv_key );
openssl_sign( "test", $signature, $pkey );
openssl_free_key( $pkey );
Согласно Руководство по PHP параметр закрытого ключа должен быть ресурсом
> priv_key_id
> resource - a key, returned by openssl_get_privatekey()
Прежде всего вы должны проверить, включен ли OpenSSL. Вы можете сделать это путем вывода
phpinfo ();
и проверьте: «Поддержка OpenSSL включена». В этом случае это было.
Для дальнейшего устранения неполадок есть две функции, которые очень помогают:
error_get_last()
Usage: print_r(error_get_last());
а также
openssl_error_string()
Usage: echo openssl_error_string();
В этом случае возвращается error_get_last ():
openssl_sign (): предоставленный ключевой параметр не может быть приведен в приватный
ключ
и «openssl_error_string ()» вернул:
ошибка: 100AE081: эллиптическая кривая
подпрограммы: EC_GROUP_new_by_curve_name: неизвестная группа
Это сообщение означает, что используемая версия OpenSSL не имеет кода для работы с используемой кривой ЕС. «EC_GROUP_new_by_curve_name» ищет «статический констант ec_list_element curve_list []» и не находит ничего. В результате он возвращает «неизвестно».
Теперь у вас есть 3 варианта:
Начиная с PHP 7.1.0 вы можете использовать:
openssl_get_curve_names()
чтобы получить список поддерживаемых кривых. Я не знаю подобной функции для PHP 5.6, поэтому вам, возможно, придется попробовать несколько, прежде чем получить ту, которая доступна на обоих хостах.
Как примечание стороны:
Некоторые дистрибутивы Linux, такие как RedHat и CentOS, используют более ограниченные версии OpenSSL, чем другие. Ошибка указывает, что это В этом случае OpenSSL был обновлен вручную на старой (5.8) версии CentOS. В Интернете есть несколько руководств (например, https://syslint.com/blog/tutorial/how-to-upgrade-openssl-on-centos-7-or-rhel-7/), которые только обновляют исполняемый файл OpenSSL. Если бы использовался этот или аналогичный метод, PHP по-прежнему использовал бы «старый» OpenSSL, и поэтому запуск OpenSSL из командной строки дал бы результат, отличный от вызовов из PHP.