使用OpenSSL和PHP在过去设置x509证书之前

时间:2014-06-18 14:28:22

标签: php openssl x509

签署证书请求的服务器的内部时钟显然比客户端计时快几秒。因此我需要设置" Not not"在我签署csr的过去几秒钟的证书中。我不想回退服务器的内部时钟,因为这似乎是一个hackish解决方案。

目前我使用以下命令签署csr并生成证书:

$usercert = @openssl_csr_sign($csr, $cacert, $privkey, intval(CERT_VAL_PERIOD), $cnf);

有没有办法通过修改openssl.cnf或使用不同的签名功能来实现我想要的目标?

2 个答案:

答案 0 :(得分:2)

使用phpseclib's pure-PHP X509 implementation ...

<?php
include 'File/X509.php';
include 'Crypt/RSA.php';

$subject = new File_X509();
$subject->loadCSR($csr);

$privkeyobj = new Crypt_RSA();
$privkeyobj->loadKey($privkey);

$issuer = new File_X509();
$issuer->loadX509($cacert);
$issuer->setPrivateKey($privkeyobj);

$x509 = new File_X509();
$x509->setSerialNumber(pack('N', time()));
$x509->setStartDate('-1 day'); // or -1 hour or whatever
$x509->setEndDate('+' . intval(CERT_VAL_PERIOD) . ' days'); // or +365 days - 2 hours or whatever

$result = $x509->sign($issuer, $subject);
echo $x509->saveX509($result);

答案 1 :(得分:0)

  

有没有办法通过修改openssl.cnf或使用不同的签名功能来实现我想要的目标?

我不相信你可以用openssl.cnf来做。我相信你必须编写自己的函数来操纵notBefore时间。

我在运行的PKI中遇到了与短期证书类似的问题。证书的生存时间为9天,包括发行日期前1天,以补偿时钟坏的移动客户端。

这是我在C ++中使用的代码,为ASN1_TIME构建X509_set_notBefore。 -23小时有一天让我回来了。 ostringstream个回转构建一个YYYYmmddHHMMSS形式的ASCII字符串(GMT为Z)。

您必须将其移植到PHP。为简洁起见,已删除错误检查。

using ASN1_TIME_ptr = unique_ptr<ASN1_TIME, decltype(&::ASN1_TIME_free)>;
...

ASN1_TIME* GetServerTimeNotBefore()
{
    int rc;
    unsigned long err;
    ostringstream oss;

    ASN1_TIME_ptr before(ASN1_TIME_new(), ::ASN1_TIME_free);
    err = ERR_get_error();
    ASSERT(before.get() != NULL);
    ...

    system_clock::time_point now = system_clock::now();
    system_clock::time_point past = now + std::chrono::hours(-23);

    time_t tt = system_clock::to_time_t(past);
    tm utc = *gmtime(&tt);

    ostringstream oss;
    oss << setw(4) << setfill('0') << utc.tm_year + 1900;
    oss << setw(2) << setfill('0') << utc.tm_mon + 1;
    oss << setw(2) << setfill('0') << utc.tm_mday;
    oss << "000000Z";

    rc = ASN1_TIME_set_string(before.get(), oss.str().c_str());
    ASSERT(rc == 1);
    ...

    return before.release();
}

它的用法如下:

ASN1_TIME_ptr before(GeServerTimeNotBefore(), ::ASN1_TIME_free);
ASSERT(before.get() != NULL);
...

rc = X509_set_notBefore(x509.get(), before.get());
err = ERR_get_error();
...