PHP 大会日本 2024

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资源
添加注释

用户贡献的注释 7 条注释

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
Joey
8 年前
我花了几小时在这个函数上发脾气,并试图用头撞桌子,试图让它加载一个公共 PEM 密钥。

即使此函数成功,它也可能在 openssl_error_string 中留下错误,因此这可能会在后面造成很多混淆。特别是如果您正在进行原型设计并且尚未对返回值进行全面检查。调用其他函数成功时也不会清除该错误。

为避免混淆,您应该始终检查返回结果,并且只有在调用返回失败(false)的 openssl 函数后才调用 openssl_error_string。
匿名
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']);
?>
GeniusLe at zslm dot org
4 年前
您可能需要从私钥导出公钥,因为其他工具生成的密钥提供的公钥是 pem 格式的,我们需要 openssh 格式

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

// 保存 $public

```
匿名
20 年前
此文档指出它可以接受 PEM 格式的私钥,但根据错误 #25614,这在任何形式下都不可能。该函数只会返回 FALSE。

唯一可以从中获取公钥的是 X.509 证书。

此外,无法将公钥导出为 PEM 编码形式。
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);
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']);
To Top