Невозможно использовать libcurl для доступа к сайту, требующему аутентификации клиента - PullRequest
5 голосов
/ 25 мая 2011

Я использую приведенный ниже код для настройки сертификата и ключа для аутентификации клиента.

  curl_easy_setopt(curl,CURLOPT_SSLCERT,"clientCert.pem");
  curl_easy_setopt(curl,CURLOPT_SSLCERTPASSWD,"changeit");
  curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
  curl_easy_setopt(curl,CURLOPT_SSLKEY,"privateKey.pem");
  curl_easy_setopt(curl,CURLOPT_SSLKEYPASSWD,"changeit");
  curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,"PEM");

Сертификат не имеет пароля, я не знаю, почему на земле существует опция SSLCERTPASSWD, я просто указал фиктивное значение. Когда я запускаю программу в Linux, я получаю код ошибки 58 и сообщение об ошибке невозможно установить файл закрытого ключа: тип privateKey.pem PEM

На Windows однако я получаю невозможно использовать клиентский сертификат (ключ не найден или неверная пароль?)

Кажется, что сертификат и ключ не совпадают, но я не знаю как. Я извлек сертификат и ключ из файла p12 с помощью команд openssl. Команда, которую я использовал для извлечения ключа:

openssl.exe pkcs12 -in client.p12 -nocerts -out privateKey.pem

и команда, используемая для извлечения сертификата:

openssl.exe pkcs12 -in client.p12 -nokeys -out clientCert.pem

Файл p12 успешно использовался в браузере для доступа к URL-адресу аутентификации клиента. Пожалуйста, помогите, прежде чем я застрелюсь.

Edit: Вот доказательство того, что закрытый ключ и сертификат соответствуют друг другу:

[debugbld@nagara ~/curlm]$ openssl x509 -noout -modulus -in clientCert.pem | openssl md5
d7207cf82b771251471672dd54c59927

[debugbld@nagara ~/curlm]$ openssl rsa -noout -modulus -in privateKey.pem | openssl md5
Enter pass phrase for privateKey.pem:
d7207cf82b771251471672dd54c59927

Так почему же это не работает?

Ответы [ 3 ]

3 голосов
/ 11 ноября 2011

Используя командную строку curl, я получил ту же ошибку, используя файл .pem, который также был получен с помощью openssl из файла p12. P12 также мог нормально работать, выполняя аутентификацию клиента при импорте в браузер. Как вы и описали, я думаю.

Моя проблема была вызвана тем, что в .pem-файле не были перечислены сертификаты в правильном порядке: кажется, что за каждым сертификатом в файле должен следовать сертификат его эмитента. Я отредактировал файл и изменил порядок секций, и curl был счастлив .

Для записи, мой оригинальный файл .p12 был получен при резервном копировании сертификата из Firefox.

Также обратите внимание, что в моем случае у меня не запрашивался пароль, и я получал

curl: (58) unable to set private key file: 'alice.pem' type PEM

перед запросом пароля

2 голосов
/ 10 декабря 2011

Я сталкивался с подобными проблемами, я обнаружил, что проблема была связана с правами доступа к файлам сертификата и закрытого ключа.Процесс, выполняющий PHP, не имел доступа для чтения к этим файлам.

Одна вещь, которую вы можете попробовать (и это помогло мне понять это), - запустить следующий код:

$result=openssl_get_privatekey('file://path/to/private/key.pem','password');

проверьте, не возвращено ли значение false и нет ли ошибок.Я получал:

file_get_contents(/path/to/private/key.pem): failed to open stream: Permission denied
0 голосов
/ 27 февраля 2013

Спасибо Хью за нить и raugfer за подсказку openssl. Позднее: и полезно, и вводит в заблуждение. ; -)

На самом деле, я решил проблему, убедившись, что путь к файлу ключа правильный. И вот почему подсказка openssl вводит в заблуждение, несмотря на то, что помогает мне проверить, в порядке ли мой файл PEM:

cURL нужен полный путь, но без префикса file: //. Пока fopen доволен относительным путем, cURL - нет. Итак, все мои тесты по открытию файла ключа прошли успешно, а cURL - нет.

Btw:.

curl_easy_setopt(curl,CURLOPT_SSLCERTPASSWD,"changeit");
curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,"PEM");

не нужны, поскольку пароль используется только для расшифровки закрытого ключа, а PEM используется по умолчанию.

...