Set notBefore of x509 certificate in the past using OpenSSL and PHP

╄→尐↘猪︶ㄣ 提交于 2019-12-22 12:21:44

问题


The internal clock of my server that signs certificate requests is apparently a few seconds faster that the client clocks. Therefore I need to set the "Not before" in the certificate a few seconds in the past when I sign a csr. I do not want to set back the internal clock of the server since that seems like a hackish solution.

Currently I sign the csr and generate a certificate using:

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

Is there any way to achieve what I want by modifying openssl.cnf or using a different signing function?


回答1:


Using 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);



回答2:


Is there any way to achieve what I want by modifying openssl.cnf or using a different signing function?

I don't believe you can do it with the openssl.cnf. I believe you will have to write your own function to manipulate the notBefore time.

I encountered a similar problem with short-lived certificates in a PKI I was running. The certificates lived 9-days, and included 1 day prior to the issue date to compensate for mobile clients with bad clocks.

Here's the code I use in C++ that builds an ASN1_TIME for X509_set_notBefore. The -23 hours moves me back one day in time. The ostringstream gyrations builds an ASCII string of the form YYYYmmddHHMMSS (with a Z for GMT).

You'll have to port it to PHP. The error checking has been removed for brevity.

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();
}

It is used like so:

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

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


来源:https://stackoverflow.com/questions/24288234/set-notbefore-of-x509-certificate-in-the-past-using-openssl-and-php

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!