Установите notBefore сертификата x509 в прошлом, используя OpenSSL и PHP
Внутренние часы моего сервера, которые подписывают запросы на сертификат, по-видимому, на несколько секунд быстрее, чем часы клиента. Поэтому мне нужно установить "Не раньше" в сертификате несколько секунд в прошлом, когда я подписываю CSR. Я не хочу сбрасывать внутренние часы сервера, так как это выглядит как хакерское решение.
В настоящее время я подписываю CSR и генерирую сертификат, используя:
$usercert = @openssl_csr_sign($csr, $cacert, $privkey, intval(CERT_VAL_PERIOD), $cnf);
Есть ли способ достичь того, что я хочу, изменив openssl.cnf или используя другую функцию подписи?
2 ответа
Используя реализацию phpseclib в чистом PHP X509...
<?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);
Есть ли способ достичь того, что я хочу, изменив openssl.cnf или используя другую функцию подписи?
Я не верю, что вы можете сделать это с openssl.cnf
, Я считаю, что вам придется написать свою собственную функцию для манипулирования notBefore
время.
Я столкнулся с подобной проблемой с недолговечными сертификатами в PKI, который я запускал. Сертификаты жили 9 дней и включали 1 день до даты выдачи, чтобы компенсировать мобильных клиентов с плохими часами.
Вот код, который я использую в C++, который создает ASN1_TIME
за X509_set_notBefore
, -23 часа возвращают меня назад на один день. ostringstream
gyrations создает строку ASCII в форме YYYYmmddHHMMSS
(с 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();
...