我想使用PHP函數openssl_verify()來驗證不同X.509證書的簽名。如何從證書中獲取簽名算法?
除了signature algorithm之外,我有它所需的全部(證書,$數據,$簽名,$ pub_key_id),但存儲在證書中。
我簡單的問題是:如何可以提取證書籤名算法?
我想使用PHP函數openssl_verify()來驗證不同X.509證書的簽名。如何從證書中獲取簽名算法?
除了signature algorithm之外,我有它所需的全部(證書,$數據,$簽名,$ pub_key_id),但存儲在證書中。
我簡單的問題是:如何可以提取證書籤名算法?
看看這個question,你可以做類似的,試試這個:
private function GetCertSignatureAlgorithm($certSignatureBinary, $pubKeyResourceId)
{
if(false === openssl_public_decrypt($certSignatureBinary, $sigString, $pubKeyResourceId))
{
return false;
}
if (empty($sigString) ||
strlen($sigString) < 5)
{
return false;
}
if (ord($sigString[0]) !== 0x30 ||
ord($sigString[2]) !== 0x30 ||
ord($sigString[4]) !== 0x06)
{
return false;
}
$sigString = substr($sigString, 4);
$len = ord($sigString[1]);
$bytes = 0;
if ($len & 0x80)
{
$bytes = ($len & 0x7f);
$len = 0;
for ($i = 0; $i < $bytes; $i++)
{
$len = ($len << 8) | ord($sigString[$i + 2]);
}
}
$oidData = substr($sigString, 2 + $bytes, $len);
$hashOid = floor(ord($oidData[0])/40) . '.' . ord($oidData[0]) % 40;
$value = 0;
for ($i = 1; $i < strlen($oidData); $i++)
{
$value = $value << 7;
$value = $value | (ord($oidData[$i]) & 0x7f);
if (!(ord($oidData[$i]) & 0x80))
{
$hashOid .= '.' . $value;
$value = 0;
}
}
//www.iana.org/assignments/hash-function-text-names/hash-function-text-names.xml
//www.php.net/manual/en/openssl.signature-algos.php
switch($hashOid)
{
case '1.2.840.113549.2.5': return 'md5';
case '1.3.14.3.2.26': return 'sha1';
case '2.16.840.1.101.3.4.2.1': return 'sha256';
case '2.16.840.1.101.3.4.2.2': return 'sha384';
case '2.16.840.1.101.3.4.2.3': return 'sha512';
//not secure = not accepted
//case '1.2.840.113549.2.2': //'md2';
//case '1.2.840.113549.2.4': //'md4';
//case '1.3.14.3.2.18': //'sha';
}
throw new Exception('CertSignatureAlgorithm not found');
}
一種方式是openssl x509 -text -noout < $certfile | grep "Signature Algorithm"
不幸的是,我只能從我的腳本調用PHP函數。 – Mike 2012-03-09 02:14:54
這個怎麼樣?
$cer = file_get_contents('certificate.cer');
$res = openssl_x509_read($cer);
openssl_x509_export($res, $out, FALSE);
$signature_algorithm = null;
if(preg_match('/^\s+Signature Algorithm:\s*(.*)\s*$/m', $out, $match)) $signature_algorithm = $match[1];
var_dump($signature_algorithm);
它產生的輸出:
string(21) "sha1WithRSAEncryption"
,你就必須映射到OPENSSL_ALGO_SHA1
自己。
啊哈!您對openssl_x509_export()使用可選參數「bool $ notext = TRUE」。簡單而巧妙的解決方案。迄今爲止最好的答案(這是不難的,因爲它是唯一的工作;-)非常感謝。 – Mike 2012-03-12 01:17:21
非常酷的解決方案 – 2012-03-14 13:39:28
使用phpseclib, a pure PHP X.509 parser ...
<?php
include('File/X509.php');
$x509 = new File_X509();
$cert = $x509->loadX509(file_get_contents('sample.pem'));
echo $cert['signatureAlgorithm']['algorithm'];
作品像一個魅力,謝謝! – Mike 2012-03-16 23:26:27