ssl — частный центр сертификации в PHP?

Я настраиваю частный CA и хочу взаимодействовать с ним, используя PHP. Я пробовал с PHP встроенная библиотека openssl. Поэтому я создаю CSR, и для подписи я использую openssl_csr_sign,

Это действительно подписывает CSR, но это все. В CLI OpenSSL это было бы что-то вроде

openssl x509 -req -days 360 -in file.csr -CA ca.crt -CAkey ca.key ...

В то время как я хочу что-то вроде

openssl ca -cert ca.crt -keyfile ca.key -in file.csr -out file.crt ...

В основном он использует модуль x509 для подписи, а не модуль ca. Так что он не записывает его в базу данных, указанную в openssl.cnf, он не использует или не обновляет серийный номер; это скорее «я доверяю этому парню, поэтому я подпишу его открытый ключ своим личным ключом», чем настоящий CA. Есть ли способ управлять частным центром сертификации в PHP с помощью openssl или нет?

1

Решение

И да и нет.

Несмотря на использование предоставленного файла openssl.conf, расширение OpenSSL в PHP не управляет автоматически базой данных сертификатов и / или серийными номерами и не предоставляет никаких утилит, помогающих с этим.

С другой стороны, сама база данных имеет относительно простой формат, так что вы можете реализовать это самостоятельно, используя примитивные функции файловой системы. Вот несколько советов, если вы действительно пойдете по этому маршруту:

  • Поскольку каждая запись сертификата находится на отдельной строке, fgets() пригодится при разборе.
    • fscanf() На первый взгляд выглядит лучше, но он одинаково обрабатывает все пробелы, и вкладки являются неотъемлемой частью формата, так что …
    • file() еще проще, но только для чтения. Скорее всего, вам понадобится одновременно чтение + запись, и вам нужно будет заблокировать файл, чтобы избежать условий гонки.
  • Строковые элементы DN могут быть в произвольном порядке, не все являются обязательными, и разделитель не экранируется, когда присутствует внутри значения, поэтому вам будет трудно создать его так же, как это делает инструмент OpenSSL CLI. Вам лучше делать openssl_x509_parse () на только что подписанный сертификат и чтение значения оттуда.
    • Я не помню, что это было, но эта функция имела небольшое различие в результатах между PHP 5 и 7, и это было отчасти важно для строки DN.
  • PHP (правильно) обрабатывает серийный номер как целое число, но он хранится в шестнадцатеричной записи, поэтому вам нужно будет конвертировать его туда и обратно.
    • Серийный файл хранит следующий серийный номер, так что вы можете сделать $serial = hexdec(file_get_contents($pathToSerial))передать эту переменную openssl_csr_sign() а потом написать sprintf("%X\n", $serial + 1) в файл.
  • Отметки времени отзыва находятся в 3-м столбце базы данных, но поскольку вы не отзываете сертификат прямо во время его подписи, он не будет представлен — поэтому между датой истечения срока действия и серийным номером есть две вкладки, не забывайте, что пока пишу.
  • Вопреки тому, что и следовало ожидать, инструмент OpenSSL CLI на самом деле не работает с тем же файлом базы данных. Он читает текущий, переименовывает его в <filename>.old а затем создает совершенно новый как <filename>, Это означает, что любое владение файловой системой, разрешения, которые предоставляют доступ к ней вашим PHP-сценариям, теряются при использовании инструмента CLI.
    • Поставьте проверки времени выполнения для доступа к файлу; при ошибке — прервать генерацию / подпись и записать / распечатать сообщение (возможно, с chown, chmod инструкции), чтобы уведомить вас об этом.
    • То же самое относится к серийным и всем остальным файлам.
  • Хотя я никогда не видел, чтобы это произошло, не исключено, что ни одно из генерации ключей, создания и подписи CSR не будет выполнено.
    • Результирующий pKey, CSR, сертификат являются взаимозависимыми и имеют тип resource (который должен быть закрыт после использования). Чтобы вызвать исключение и закрыть ресурсы только при необходимости, я предпочитаю предварительно определять переменные, содержащие их, и use они в замыкании, которое обрабатывает все условные подпрограммы, свободные от ресурсов, перед выдачей исключения.
    • Записывать в базу данных можно только после того, как все 3 успешно выполнены, и записывать в последовательный файл последним.
  • Вы, наверное, уже поняли это, но ресурс pKey содержит как закрытый, так и открытый ключи.

Как вы можете видеть, это управляемо, если вы знаете, что делаете, но у него много ошибок, и оно не стоит того, чтобы использовать простой PoC. Вызов инструмента CLI через exec() (и братья и сестры) является более простым выбором.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]