PHP Conference Japan 2024

openssl_x509_parse

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

openssl_x509_parse解析 X509 证书并将其信息作为数组返回

描述

openssl_x509_parse(OpenSSLCertificate|string $certificate, bool $short_names = true): array|false

openssl_x509_parse() 返回有关提供的 certificate 的信息,包括主题名称、颁发者名称、用途、有效期等字段。

参数

certificate

X509 证书。有关有效值的列表,请参阅 密钥/证书参数

short_names

short_names 控制数组中数据的索引方式 - 如果 short_namestrue(默认值),则字段将使用短名称形式进行索引,否则将使用长名称形式 - 例如:CN 是 commonName 的短名称形式。

返回值

返回数据的结构(有意)尚未记录,因为它仍在发生变化。

变更日志

版本 描述
8.0.0 certificate 现在接受 OpenSSLCertificate 实例;以前,接受类型为 OpenSSL X.509资源
添加注释

用户贡献的注释 7 个注释

8
nathanael at dihedral dot de
18 年前
处理 x509 crt 文件的用途时
openssl_x509_parse 的输出给出一个数组,其中包含以下用途
每个新数组(例如 [purposes][1]、[purposes][2])都是一个新的用途检查
我将此输出与以下命令的输出进行了比较
# openssl x509 -purpose -in <x509crt_file>
我得到的结果是
[purposes][x][2] 很明显是所检查用途的名称
[purposes][x][1] 对应于作为 CA 的测试用途(如 [purposes][x][2] 中命名的那样)
[purposes][x][0] 对应于用途的一般可用性

[purposes] => 数组
(
[1] => 数组
(
[0] => 1
[1] => 1
[2] => sslclient
)

[2] => 数组
(
[0] => 1
[1] => 1
[2] => sslserver
)

[3] => 数组
(
[0] => 1
[1] => 1
[2] => nssslserver
)

[4] => 数组
(
[0] => 1
[1] => 1
[2] => smimesign
)

[5] => 数组
(
[0] => 1
[1] => 1
[2] => smimeencrypt
)

[6] => 数组
(
[0] => 1
[1] => 1
[2] => crlsign
)

[7] => 数组
(
[0] => 1
[1] => 1
[2] => any
)

[8] => 数组
(
[0] => 1
[1] => 1
[2] => ocsphelper
)

)
3
maarten at xolphin dot nl
19 年前
目前缺少非常有用的 X509 OID(如 streetAddress、postalCode 等)。您可以在 http://www.alvestrand.no/objectid/2.5.4.html, 找到它们的列表,我希望它们很快就会包含在 openssl-x509-parse 中。

在此之前,您仍然可以通过以下方式获取这些 OID

<?
function getOID($OID, $ssl)
{
preg_match('/\/' . $OID . '=([^\/]+)/', $ssl, $matches);
return $matches[1];
}

$cert = file_get_contents('test.crt');
$ssl = openssl_x509_parse($cert);
$Address = getOID('2.5.4.9', $ssl['name']);
$ZipCode = getOID('2.5.4.17', $ssl['name']);
$Postbox = getOID('2.5.4.18', $ssl['name']);
?>

Horde 框架中的 parseCert 函数对此也很有用。
1
Stilez
8 年前
有效期信息以两种不同的格式返回两次。它们可以像这样转换为正常的日期时间对象

$x509_data = openssl_x509_parse($cert);
date_create_from_format('ymdHise', $x509_data['validFrom'])->format('c');
date_create( '@' . $x509_data['validFrom_time_t'])->format('c');
/* 这些给出相同的结果 */

要直接获取人类可读的格式(或任何其他格式化的字符串)而不是日期时间对象,请使用此方法

date_create_from_format('ymdHise', $x509_data['validFrom'])->format('c');

date_create( '@' . $x509_data['validFrom_time_t'])->format('c');

同样适用于 validTo 和 validTo_time_t
2
smgallo at buffalo dot edu
20 年前
证书名称和主题数组中电子邮件部分的标识符自 PHP4 以来已更改。在 PHP 4.3.0 中,返回以下数组(由 print_r() 显示)

[name] => /O=Grid/O=Globus/O=CCR Grid Portal/OU=Portal User/CN=Test User/[email protected]
[subject] => 数组
(
[O] => Grid/O=Globus/O=CCR Grid Portal
[OU] => Portal User
[CN] => Test User
[Email] => [email protected]
...

PHP5 中的结果是(注意 Email -> emailAddress)

[name] => /O=Grid/O=Globus/O=CCR Grid Portal/OU=Portal User/CN=Test User/[email protected]
[subject] => 数组
(
[O] => Grid/O=Globus/O=CCR Grid Portal
[OU] => Portal User
[CN] => Test User
[emailAddress] => [email protected]
...

当然,手册确实说可能会发生这种情况。 :)
1
s dot stok at rollerscapes dot net
14 年前
备用主题可以作为扩展读取。

[extensions]
[subjectAltName] => DNS:*.cacert.org, DNS:cacert.org, DNS:*.cacert.net, DNS:cacert.net, DNS:*.cacert.com, DNS:cacert.com
2
koukopoulos at gmail dot com
16 年前
关于前面的注释:对 x509v3 扩展的支持已在 PHP 5.2 中添加。同样在 5.2.4 之前的 PHP5 中,x509v3 扩展的值未解码,并以 DER 二进制表示形式返回。因此,为了读取 v3 扩展的内容,您必须自己解析相关的 ASN.1 结构。

例如,如果需要在具有 OID 1.3.6.1.4.1.7782.3.3 的私有扩展中读取 IA5STRING 值,则可以执行

<?php

/* 解析 DER 编码的 IA5STRING 表示
长度小于 127 */
function asn1der_ia5string($str)
{
$len=strlen($str)-2;
if (
$len < 0 && $len > 127) {
return
false;
}

/* 检查标签和长度 */
if (22 != (ord($str[$pos++]) & 0x1f) &&
ord($str[$pos++]) != $len) {
/* 不是 IA5STRING 的有效 DER 编码 */
return false;
}

return
substr($str, 2, $len);
}
$cert = openssl_x509_parse($pemcert);
print (
asn1der_ia5string($cert['extensions']['1.3.6.1.4.1.7782.3.3'])); // 输出解码后的 ASCII 字符串

?>

在更新的版本(>5.2.3)中,扩展名以“可读格式”返回。例如

<?php print_r(openssl_x509_parse(...)); ?>
将得到
<?
数组
(
[名称] => /C=GR/O=SOMETHING/CN=ME/
...
[扩展名] => 数组
(
[basicConstraints] => CA:FALSE
[keyUsage] => 数字签名,不可否认,密钥加密
[extendedKeyUsage] => 电子邮件保护,TLS Web 客户端身份验证
[nsCertType] => SSL 客户端,S/MIME
....
?>
-4
zioproto at gmail dot com
16 年前
如果您知道 OID,则可以通过以下方式读取 X.509 证书中的扩展名

//从文件中读取证书
$cert = file_get_contents('test.crt');
$ssl = openssl_x509_parse($cert);

$ext_value = $ssl['extensions']['1.2.3.4.5.6'];
echo $ext_value

--------------------------------

由于 $ssl 数组没有文档记录,您可以轻松查看其内容,如下所示

//打印所有数组!
print_r(array_values($ssl));
print_r(array_keys($ssl));
To Top