2012-03-09 28 views

回答

5

看看這個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'); 
} 
+0

作品像一個魅力,謝謝! – Mike 2012-03-16 23:26:27

-1

一種方式是openssl x509 -text -noout < $certfile | grep "Signature Algorithm"

+0

不幸的是,我只能從我的腳本調用PHP函數。 – Mike 2012-03-09 02:14:54

6

這個怎麼樣?

$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自己。

+0

啊哈!您對openssl_x509_export()使用可選參數「bool $ notext = TRUE」。簡單而巧妙的解決方案。迄今爲止最好的答案(這是不難的,因爲它是唯一的工作;-)非常感謝。 – Mike 2012-03-12 01:17:21

+0

非常酷的解決方案 – 2012-03-14 13:39:28

1

使用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'];