Php 如何从证书中获取签名算法?

Php 如何从证书中获取签名算法?,php,openssl,certificate,x509certificate,Php,Openssl,Certificate,X509certificate,我想使用PHP函数来验证不同X.509证书的签名 我拥有它所需要的一切(证书、$data、$signature、$pub_key_id),除了存储在证书中的but 我的简单问题是:如何从证书中提取签名算法?一种方法可能是opensslx509-text-noout

我想使用PHP函数来验证不同X.509证书的签名

我拥有它所需要的一切(证书、$data、$signature、$pub_key_id),除了存储在证书中的but


我的简单问题是:如何从证书中提取签名算法?

一种方法可能是
opensslx509-text-noout<$certfile | grep“签名算法”

如何

$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\u ALGO\u SHA1

看看这个,您可以做类似的事情,试试这个:

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');
}
私有函数GetCertSignatureAlgorithm($certSignatureBinary,$pubKeyResourceId)
{
if(false==openssl\u public\u decrypt($certSignatureBinary,$sigString,$pubKeyResourceId))
{
返回false;
}
if(空($sigString)||
strlen($sigString)<5)
{
返回false;
}
如果(ord($sigString[0])!==0x30||
ord($sigString[2])!==0x30||
ord($sigString[4])!==0x06)
{
返回false;
}
$sigString=substr($sigString,4);
$len=ord($sigString[1]);
$bytes=0;
如果($len&0x80)
{
$bytes=($len&0x7f);
$len=0;
对于($i=0;$i<$bytes;$i++)
{
$len=($len使用


不幸的是,我只能从我的script.aha中调用PHP函数!您正在为openssl_x509_export()使用可选参数“bool$notext=TRUE”。这是一个简单而聪明的解决方案。目前为止最好的答案(这并不难,因为它是唯一有效的;-)非常感谢。
<?php
include('File/X509.php');

$x509 = new File_X509();
$cert = $x509->loadX509(file_get_contents('sample.pem'));
echo $cert['signatureAlgorithm']['algorithm'];