带有openSSL的PHP - 提供的密钥参数不能强制转换为私钥

问题描述 投票:4回答:2

我正在尝试使用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。为什么一台服务器能够使用密钥而一台服务器不能?

php pyopenssl
2个回答
0
投票

也许您需要使用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 manual,私钥参数必须是资源

> priv_key_id
> resource - a key, returned by openssl_get_privatekey()

0
投票

首先,您应该检查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曲线。 “EC_GROUP_new_by_curve_name”搜索“static const ec_list_element curve_list []”并找不到。结果它返回“未知”。

现在你有3个选择:

  • 升级OpenSSL以支持此曲线。
  • 选择两台服务器上支持的另一条曲线。
  • 使用非EC加密。

从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调用不同的结果。

© www.soinside.com 2019 - 2024. All rights reserved.