На Ubuntu 14.04.3 этот код работает нормально:
$url_login = "https://test.example.com/login.do";
$cert_file = '/var/www/html/test/cert.pem';
$ssl_key = '/var/www/html/test/cert_private.pem';
$post_fields = 'userAction=1&cancelReason=&cancelType=&account=&memoType=&userText=&userid=99999999&password=xxxxxxxxxxxxxxxx';
$ch = curl_init();
$options = array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_HEADER => 1,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_SSL_VERIFYHOST => 0,
CURLOPT_SSL_VERIFYPEER => 0,
CURLOPT_USERAGENT => 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)',
CURLOPT_VERBOSE => 0,
CURLOPT_URL => $url_login ,
CURLOPT_SSLCERT => $cert_file ,
CURLOPT_SSLCERTTYPE, 'PEM',
CURLOPT_SSLKEY => $ssl_key,
CURLOPT_COOKIESESSION => 1,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post_fields
);
curl_setopt_array($ch , $options);
$output = curl_exec($ch);
PHP на Ubuntu использует curl с openssl.
На Centos 7, если не удается с:
Curl Error : SSL peer was unable to negotiate an acceptable set of security parameters.
Керл здесь с NSS.
«Cert.pem» содержит только сертификат клиента с цепочкой сертификатов, а «cert_private.pem» содержит закрытый ключ, не защищенный паролем. (—— НАЧАТЬ RSA ЧАСТНЫЙ КЛЮЧ ——).
Как я могу получить вышеупомянутый код PHP работать с обоими? OpenSSL и NSS реализации curl?
Как насчет исправления:
CURLOPT_SSLCERTTYPE, 'PEM',
в
CURLOPT_SSLCERTTYPE => 'PEM',
?
Я также сталкивался с этой проблемой, используя аутентификацию сертификата клиента с помощью nss, в то время как openssl работает нормально.
После большого тестирования я установил на сервере, с которым мы пытаемся связаться:
Вышеописанное происходит независимо от набора шифров, обычно мы используем rsa_aes_256_cbc_sha_256.
Быстрый способ обойти TLS v1.0:
CURLOPT_SSLVERSION => 4,
Очевидно, что это не идеально, и ваш сервер может не поддерживать его.
Другой вариант — скомпилировать curl с помощью openssl или даже GnuTLS (хотя я не проверял последнее) вместо nss. Опять же, это не может быть вариантом.
Пока что это указывает на проблему с NSS. Я обновлю этот ответ, если дальнейшая отладка даст какую-либо полезную информацию.
Просто для справки, это полное сообщение об ошибке с использованием curl в командной строке:
* NSS error -12227 (SSL_ERROR_HANDSHAKE_FAILURE_ALERT)
* SSL peer was unable to negotiate an acceptable set of security parameters.
* Closing connection 0
curl: (35) SSL peer was unable to negotiate an acceptable set of security parameters.
Обновление 2015-11-24: Дальнейшее тестирование с Wireshark и ssltap показало, что начальное рукопожатие прошло успешно, и соединение доходит до клиента, отправляющего ChangeCipherSpec, за которым следует его зашифрованное сообщение «Завершено».
Затем сервер должен расшифровать клиентское сообщение «Завершено», проверить хэш и MAC-адрес и ответить собственным зашифрованным сообщением «Завершено». Вместо этого сервер отвечает «handshake_failure» в этот момент.
Это должно дать представление о том, где происходит сбой NSS.
Chrome, Openssl и Charles Proxy могут аутентифицироваться с использованием сертификата клиента. Firefox (с использованием NSS) и curl (с NSS) оба терпят неудачу в этой точке.
Обновление 2015-11-27: Дополнительная информация, предоставленная операционной группой сервера, предполагает, что это может быть проблема с несовместимым сервером. Проблема возникает только при использовании TLS 1.2 при определенных обстоятельствах. Это объясняет, почему некоторые библиотеки SSL, такие как OpenSSL, достаточно гибки, чтобы обойти это.
НСС может быть более строгим в соответствии с RFC. Я обновлю ответ, если / когда мы услышим больше от операционной команды, управляющей сервером.
Обновление 2017-01-25: Программное обеспечение веб-сервера и балансировщики нагрузки создаются специально для платежного шлюза конкретного банка. Мы недавно попробовали еще раз с новым клиентом, и теперь сервер, похоже, работает с Curl, созданным либо с NSS, либо с OpenSSL, и больше не видит ошибку. В итоге: обходной путь должен был использовать другую библиотеку SSL и ждать, пока разработчики исправят серверное программное обеспечение.