2024 日本 PHP 研討會

openssl_x509_parse

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

openssl_x509_parse解析 X509 憑證並將資訊以陣列形式返回

說明

openssl_x509_parse(OpenSSLCertificate|字串 $certificate, 布林 $short_names = true): 陣列|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); // 使用正規表達式從 $ssl 中提取 OID 的值
return $matches[1]; // 返回提取到的 OID 值
}

$cert = file_get_contents('test.crt'); // 讀取證書檔案內容
$ssl = openssl_x509_parse($cert); // 解析 X.509 證書
$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 函式也可以用於此用途。 // 建議使用 Horde 框架的 parseCert 函式
1
Stilez
8 年前
有效日期資訊會以兩種不同格式返回兩次。它們可以轉換為一般的日期時間物件,如下所示:

$x509_data = openssl_x509_parse($cert); // 解析 X.509 證書資料
date_create_from_format('ymdHise', $x509_data['validFrom'])->format('c'); // 將 validFrom 轉換為日期時間物件
date_create( '@' . $x509_data['validFrom_time_t'])->format('c'); // 將 validFrom_time_t 轉換為日期時間物件
/* 這兩者會得到相同的結果 */

若要直接取得易於理解的格式(或任何其他格式的字串),而不是日期時間物件,請使用以下方式:

date_create_from_format('ymdHise', $x509_data['validFrom'])->format('c'); // 將 validFrom 轉換為日期時間物件

date_create( '@' . $x509_data['validFrom_time_t'])->format('c'); // 將 validFrom_time_t 轉換為日期時間物件

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=test@nospam.buffalo.edu
[subject] => 陣列
(
[O] => Grid/O=Globus/O=CCR Grid Portal
[OU] => Portal User
[CN] => Test User
[Email] => test@nospam.buffalo.edu
...

PHP5 中的結果如下(注意 Email -> emailAddress):

[name] => /O=Grid/O=Globus/O=CCR Grid Portal/OU=Portal User/CN=Test User/emailAddress=test@nospam.buffalo.edu
[subject] => 陣列
(
[O] => Grid/O=Globus/O=CCR Grid Portal
[OU] => Portal User
[CN] => Test User
[emailAddress] => test@nospam.buffalo.edu
...

當然,手冊確實有提到這種情況可能會發生。 :)
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 年前
關於先前的注意事項:PHP 5.2 中新增了對 x509v3 擴充套件的支援。同樣在 5.2.4 之前的 PHP5 中,x509v3 擴充套件的值未被解碼,而是以 DER 二進位表示法返回。因此,為了讀取 v3 擴充套件的內容,您必須自行解析相關的 ASN.1 結構。

例如,如果需要讀取 OID 為 1.3.6.1.4.1.7782.3.3 的私有擴充套件中的 IA5STRING 值,可以執行以下操作:

<?php

/* 解析 DER 編碼表示的長度小於 127 的 IA5STRING */
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(...)); ?>
會產生
<?
陣列
(
[name] => /C=GR/O=SOMETHING/CN=ME/
...
[extensions] => 陣列
(
[basicConstraints] => CA:FALSE
[keyUsage] => 數位簽章、不可否認性、金鑰加密
[extendedKeyUsage] => 電子郵件保護、TLS 網頁用戶端驗證
[nsCertType] => SSL 用戶端、S/MIME
....
?>
-4
zioproto at gmail dot com
16 年前
要從 X.509 憑證讀取擴展,如果您知道 OID,可以這樣做

//從檔案讀取憑證
$cert = file_get_contents('test.crt'); // 讀取證書檔案內容
$ssl = openssl_x509_parse($cert); // 解析 X.509 證書

$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