openssl_pkey_get_public

(PHP 4 >= 4.2.0, PHP 5, PHP 7, PHP 8)

openssl_pkey_get_public从证书中提取公钥并准备用于使用

描述

openssl_pkey_get_public()public_key 中提取公钥并准备用于其他函数。

参数

public_key

public_key 可以是以下之一:

  1. 一个 OpenSSLAsymmetricKey 实例
  2. 一个具有 file://path/to/file.pem 格式的字符串。该命名文件必须包含 PEM 编码的证书/公钥(它可能包含两者)。
  3. 一个 PEM 格式的公钥。

返回值

成功时返回一个 OpenSSLAsymmetricKey 实例,出错时返回 false

变更日志

版本 描述
8.0.0 成功时,此函数现在返回一个 OpenSSLAsymmetricKey 实例;以前,返回的是类型为 OpenSSL key资源
8.0.0 public_key 现在接受一个 OpenSSLAsymmetricKeyOpenSSLCertificate 实例;以前,接受的是类型为 OpenSSL keyOpenSSL X.509资源
添加注释

用户贡献的注释 12 个注释

10
info at steyla dot com
13 年前
如果您试图读取 PKCS#1 RSA 公钥,您会遇到麻烦,因为 openssl 希望公钥采用 X.509 样式。

PKCS#1 RSA 公钥

-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAgYxTW5Yj+5QiQtlPMnS9kqQ/HVp+T2KtmvShe68cm8luR7Dampmb
[...]
cbn6n2FsV91BlEnrAKq65PGJxcwcH5+aJwIDAQAB
-----END RSA PUBLIC KEY-----

.. 不可读,而 X.509 样式的公钥

-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgYxTW5Yj+5QiQtlPMnS9
[..]
JwIDAQAB
-----END PUBLIC KEY-----

是可读的。您可以使用一个简单(且粗陋)的解决方法来读取 PKCS#1 RSA。X.509 样式的公钥的前几个字节包含头信息,可以无耻地复制。

换句话说:从上面的 X.509 密钥中删除第一个 32 字节之后的所有内容(从 Q8A 后面开始),并将您的 PKCS#1 数据附加到该密钥,重新格式化为 64 字节长度,并与 openssl 一起使用。

请注意:以上示例仅适用于 2048 位长度。

正如我所说 - 这是一个有点粗陋的方法 - 但嘿 - 如果你像我一样绝望。

Michaela
3
Joey
7 年前
我花了好几个小时与这个函数搏斗,并试图让它加载一个公共 PEM 密钥,最后撞到桌子上,头都撞疼了。

即使成功了,此函数也可能会在 openssl_error_string 中留下错误,因此这会导致后续出现很多混乱。尤其是在您进行原型设计并且尚未对返回值进行全面检查时。即使成功调用其他函数,错误也不会被清除。

为了避免混淆,您应该始终检查返回值,并且只有在调用返回失败(false)的 openssl 函数之后才能调用 openssl_error_string。
2
Anonymous
17 年前
您可以使用 openssl_pkey_get_details(resource $key ) 函数获取(并保存到文件)公钥

<?php
$pub_key
= openssl_pkey_get_public(file_get_contents('./cert.crt'));
$keyData = openssl_pkey_get_details($pub_key);
file_put_contents('./key.pub', $keyData['key']);
?>
0
GeniusLe at zslm dot org
3 年前
您可能需要从私钥中导出公钥,因为由其他工具生成的密钥提供的公钥是 pem 格式的,而我们需要 openssh 格式

```
<?php
$public
= openssl_pkey_get_details(openssl_pkey_get_private(OPENSSL_USER_PRIVATE_KYE))['key'];

// save $public

```
0
Anonymous
20 年前
此文档指出它可以获取 PEM 格式的私钥,但根据 bug #25614,这是不可能的。该函数只是返回 FALSE。

您只能从 X.509 证书中获取公钥。

此外,没有办法将公钥导出为 PEM 编码格式。
-1
dankybastard at hotmail
19 年前
您还必须使用证书的字符串表示形式来获取公钥资源

$dn = array(); // 使用默认值
$res_privkey = openssl_pkey_new();
$res_csr = openssl_csr_new($dn, $res_privkey);
$res_cert = openssl_csr_sign($res_csr, null, $res_privkey, $ndays);

openssl_x509_export($res_cert, $str_cert);

$res_pubkey = openssl_pkey_get_public($str_cert);
-6
ppostma1
13 年前
发现 2048 位的证书/公钥是这种格式

-----BEGIN PUBLIC KEY-----
X509 签名 + PEM 签名 + 模数 + 'ID' + 指数
-----END PUBLIC KEY-----

所以变量是
-----BEGIN PUBLIC KEY-----
'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A' . 'MIIBCgKCAQEA' . $modulus . 'ID' . $exponent
-----END PUBLIC KEY-----

<?php wordwrap($cert, 64, "\r\n", true); ?>
-5
VaD
16 年前
此代码中有一个小错误

$pub_key = openssl_pkey_get_public(file_get_contents('./cert.crt'));
$keyData = openssl_pkey_get_details($pub_key);
file_put_contents('./key.pub', $keyData['key']);
-8
igniweb dot net at gmail dot com
6 年前
完成 https://php.net/manual/fr/function.openssl-pkey-get-public.php#101513

Michaela 的代码重写可以是

$key = str_replace([
'-----BEGIN RSA PUBLIC KEY-----',
'-----END RSA PUBLIC KEY-----',
"\r\n",
"\n",
], [
'',
'',
"\n",
''
], $key);

$key = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A' . trim($key);

$key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
-10
Paul Clark
14 年前
请注意,这将从 PEM 格式的公钥中读取公钥

<?php
$key
= <<<EOF
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDXX/MsKEBLcLeKA1d/i7ufG1qs
qS97xFkIRSeX3TwmHic843AfVrzoh2pZUeOvK9ZLZQpHSM7DoHMYDGD1273+FvZX
Ypf5LiFtecfxko/Cku16zy6WAeCYVFjjlveBhwPmPCIk+qDRYeiIW05QE2XK+CuD
nJ7sxxXIJSSgD3Jo5wIDAQAB
-----END PUBLIC KEY-----
EOF;

print
$key;
$res = openssl_pkey_get_public($key);
print_r(openssl_pkey_get_details($res));
?>

请注意,与文档相反,openssl_pkey_get_details() *不会* 直接读取 PEM,您必须通过此步骤。
-9
thelen dot shar at gmail dot com
15 年前
由于缺乏文档,我很难理解这一点。

但我遵循的所有步骤都是
生成私钥
openssl genrsa -des3 -out private.pem 1024

生成公钥
openssl rsa -in private.pem -out public.pem -outform PEM -pubout

然后在 PHP 中
$passphrase = 'somestring';
$key_private = openssl_get_privatekey(file_get_contents('private.pem'), $passphrase);
$key_public = openssl_get_publickey(file_get_contents('public.pem'));

这可能不是最好的方法,但比网站上的其他示例简单得多。我在获取公钥时遇到了一些麻烦,它并没有很好地指定,而且我在生成它时犯了一个错误,因此它也因此无法正常工作。
-14
Rurri
12 年前
如果您有一个 4096 位密钥对,并且尝试使用以以下开头:

-----BEGIN RSA PUBLIC KEY-----

的公钥

并且您需要将其转换为此函数可以使用,则可以通过添加静态标题信息来将其转换

MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A

例如
$start_key = str_replace('-----BEGIN RSA PUBLIC KEY-----', '', $start_key);
$start_key = trim(str_replace('-----END RSA PUBLIC KEY-----', '', $start_key));
$key = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($key, 64, "\n", true) . "\n-----END PUBLIC KEY-----";
To Top