【问题标题】:PHP SSL Certificate Serial Number in hexadecimal十六进制的 PHP SSL 证书序列号
【发布时间】:2011-06-21 13:53:26
【问题描述】:
我需要显示有关序列号的 SSL 证书信息。
当我使用
$cert = file_get_contents('mycert.crt');
$data=openssl_x509_parse($cert,true);
$data['serialNumber']
我收到喜欢
-5573199485241205751
但是当我运行命令时
openssl x509 -in 'mycert.crt' -noout -serial
我收到
序列号=B2A80498A3CEDC09
是否可以在 PHP 中接收?
谢谢。
【问题讨论】:
标签:
php
security
ssl
x509
serial-number
【解决方案1】:
您可能以字节数组的形式接收序列号。将这些字节转换为十六进制,您应该得到使用 openssl 看到的序列号。
【解决方案2】:
感谢 Petey B 这个想法很有趣,所以帮助我找到了搜索的方向。
解决办法是:
$serial_number= strtoupper(dechex($serial_number));
【解决方案3】:
php > $value = hexdec('B2A80498A3CEDC09');
php > echo dechex($value);
b2a80498a3cee000
这似乎不起作用。可能是由于浮点转换。
我看到了一种使用 bcmath 的解决方案。
来自 confusa(http://www.assembla.com/code/confusa/git/nodes/lib/ca/Certificate.php?rev=a80a040c97fde2c170bb290d756c6729883fe80a):
/*
* PHP will return the serial as an integer, whereas
* everybody else use the hex-represenatation of the
* number.
*
* Due to the fact that Comodo uses *insanely* large
* serial-numbers, we need to be a bit creative when we
* get the serial as PHP won't cope with numbers larger
* than MAX_INT (2**32 on 32 bits arch)
*/
$serial = $this->x509_parsed['serialNumber'] . "";
$base = bcpow("2", "32");
$counter = 100;
$res = "";
$val = $serial;
while($counter > 0 && $val > 0) {
$counter = $counter - 1;
$tmpres = dechex(bcmod($val, $base)) . "";
/* adjust for 0's */
for ($i = 8-strlen($tmpres); $i > 0; $i = $i-1) {
$tmpres = "0$tmpres";
}
$res = $tmpres .$res;
$val = bcdiv($val, $base);
}
if ($counter <= 0) {
return false;
}
return strtoupper($res);
我没有启用 bcmath,所以目前无法测试。
【解决方案4】:
您可以为此目的使用phpseclib:
<?php
include('Math/BigInteger.php');
$cert_body = file_get_contents('mycert.crt');
$cert_decoded = openssl_x509_parse($cert_body, true);
echo $cert_decoded['serialNumber'] // outputs 5573199485241205751
$cert_serial = new Math_BigInteger($cert_decoded['serialNumber']);
$cert_serial = strtoupper($cert_serial->toHex());
echo $cert_serial // outputs B2A80498A3CEDC09
?>