Почему мы видим ошибку certificate has expired?
Почему так происходит подробно расписано на хабре.
Curl: (60) проблема с сертификатом ssl: невозможно получить сертификат локального эмитента
Я тоже столкнулся с этой проблемой. Я читал эту ветку, и большинство ответов для меня информативно, но слишком сложно. У меня нет опыта в сетевых темах, поэтому этот ответ для таких людей, как я.
В моем случае эта ошибка произошла из-за того, что я не включил промежуточный и корневой сертификаты рядом с сертификатом, который использовал в своем приложении.
Вот что я получил от поставщика SSL-сертификатов:
- abc.crt
- abc.pem
- abc-bunde.crt
В abc.crtфайле был только один сертификат:
-----BEGIN CERTIFICATE-----
/*certificate content here*/
-----END CERTIFICATE-----
Если бы я предоставил его в этом формате, браузер не отображал бы никаких ошибок (Firefox), но я получил бы curl: (60) SSL certificate : unable to get local issuer certificateошибку, когда сделал запрос curl.
Чтобы исправить эту ошибку, проверьте свой abc-bunde.crtфайл. Скорее всего, вы увидите что-то вроде этого:
-----BEGIN CERTIFICATE-----
/*additional certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*other certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*different certificate content here*/
-----END CERTIFICATE-----
Это ваши промежуточные и корневые сертификаты. Произошла ошибка, поскольку они отсутствуют в сертификате SSL, который вы предоставляете приложению.
Чтобы исправить ошибку, объедините содержимое обоих этих файлов в следующем формате:
-----BEGIN CERTIFICATE-----
/*certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*additional certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*other certificate content here*/
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
/*different certificate content here*/
-----END CERTIFICATE-----
Обратите внимание, что между сертификатами нет пробелов в конце или в начале файла. После того, как вы предоставите этот комбинированный сертификат для вашего приложения, ваша проблема должна быть решена.
Php: curl_setopt – manual
curl is especially difficult to work with when it comes to cookies. So I will talk about what I found with PHP 5.6 and curl 7.26.
If you want to manage cookies in memory without using files including reading, writing and clearing custom cookies then continue reading.
To start with, the way to enable in memory only cookies associated with a cURL handle you should use:
curl_setopt($curl, CURLOPT_COOKIEFILE, “”);
cURL likes to use magic strings in options as special commands. Rather than having an option to enable the cookie engine in memory it uses a magic string to do that. Although vaguely the documentation here mentions this however most people like me wouldn’t even read that because a COOKIEFILE is the complete opposite of what we want.
To get the cookies for a curl handle you can use:
curl_getinfo($curl, CURLINFO_COOKIELIST);
This will give an array containing a string for each cookie. It is tab delimited and unfortunately you will have to parse it yourself if you want to do anything beyond copying the cookies.
To clear the in memory cookies for a cURL handle you can use:
curl_setopt($curl, CURLOPT_COOKIELIST, “ALL”);
This is a magic string. There are others in the cURL documentation. If a magic string isn’t used, this field should take a cookie in the same string format as in getinfo for the cookielist constant. This can be used to delete individual cookies although it’s not the most elegant API for doing so.
For copying cookies I recommend using curl_share_init.
You can also copy cookies from one handle to another like so:
foreach(curl_getinfo($curl_a, CURLINFO_COOKIELIST) as $cookie_line)
curl_setopt($curl, CURLOPT_COOKIELIST, $cookie_line);
An inelegant way to delete a cookie would be to skip the one you don’t want.
I only recommend using COOKIELIST with magic strings because the cookie format is not secure or stable. You can inject tabs into at least path and name so it becomes impossible to parse reliably. If you must parse this then to keep it secure I recommend prohibiting more than 6 tabs in the content which probably isn’t a big loss to most people.
A the absolute minimum for validation I would suggest:
/^([^t] t){5}[^t] $/D
Here is the format:
#define SEP “t” /* Tab separates the fields */
char *my_cookie =
“example.com” /* Hostname */
SEP “FALSE” /* Include subdomains */
SEP “/” /* Path */
SEP “FALSE” /* Secure */
SEP “0” /* Expiry in epoch time format. 0 == Session */
SEP “foo” /* Name */
SEP “bar”; /* Value */
Ssl из php: socket и curl
Сегодня, этим сонным летним утром, я расскажу вам про SSL соединение из PHP скрипта. Расскажу исходя не только лишь из теории, а ещё и решая вполне себе практическую задачу — логин на гугловский блогосервис blogger.com.
Начнём с сокетов. В хелпе заявлена возможность использования HTTPS протокола, поэтому пробуем. Набор POST переменных взят из developer’s guide. Хабрапарсер обрамляет мыло ссылкой, поэтому “@” заменена на (at).
$postvars = array(
"Email" => "mail(at)gmail.com",
"Passwd" => "pass",
"service" => "blogger"
);
$postdata = “”;
foreach ( $postvars as $key => $value )
$postdata .= “&”.rawurlencode($key).”=”.rawurlencode($value);
$postdata = substr( $postdata, 1 );
$fp = fsockopen(“ssl://google.com”, 443);
$send = “”;
$send .= “POST /accounts/ClientLogin HTTP/1.1rn”;
$send .= “Host: google.comrn”;
$send .= “Content-length: “.strlen($postdata).”rn”;
$send .= “Content-type: text/plainrn”;
$send .= “Connection: closern”;
$send .= “rn”;
$send .= $postdata.”rnrn”;
fputs($fp, $send);
$html = fread($fp, 1000000);
fclose($fp);
echo “”.$html.””;
В функции fsockopen в качестве префикса перед именем сервера используем не https, а ssl. Так прямым текстом написано в хелпе. Дальше всё просто. Формируем HTTP-header, и пихаем его в открытый сокет. Читаем ответ, и получаем
Error=BadAuthentication
Короче, если опустить часовые мытарства и пляски вокруг функций сокета, у меня ничего не вышло. Ну то есть не вышло передать POST данные, хотя GET запросы возвращаются нормально. Может это связано только с гугловским сервером, а где-то в другом месте получится.
UPD. Огромное спасибо хабраюзеру anabolik, который подсказал что если изменить одну строку заголовка и сделать $send .= "Content-type: application/x-www-form-urlencodedrn";
то всё сразу заработает. Ещё раз спасибо. Отблагодарил всякими способами =).
Переходим ко второму способу.
Открываем страницу мана про cURL и радуемся. Столько возможностей для запросов, для всякого конфигурирования. Должно получиться. Итак, лезем в curl_setopt. Нам понадобятся
CURLOPT_URL — это URL запроса.
CURLOPT_POST — говорим, что будем посылать POST запрос.
CURLOPT_POSTFIELDS — собственно POST переменыые.
CURLOPT_RETURNTRANSFER — вернуть результат запроса, а не выводить в браузер.
Теперь собственно о SSL параметрах:
CURLOPT_SSL_VERIFYPEER — если поставить его в 0, то удалённый сервер не будет проверять наш сертификат. В противном случае необходимо этот самый сертификат послать.
CURLOPT_CAINFO — указывать файл сертификата, если CURLOPT_SSL_VERIFYPEER установлен в 1.
CURLOPT_SSLVERSION — целое число, указывает версию SSL (2 или 3), обычно определяется автоматически.
CURLOPT_SSL_VERIFYHOST — будет ли производиться проверка имени удалённого сервера, указанного в сертификате. Если установить значение «2», то будет произведена ещё и проверка соответствия имени хоста. (если честно, я так и не понял что делает этот флаг)
Вот и всё. Нам для гугла понадобится только указать, что мы с собой никаких сертификатов не принесли, пустите нас так пожалуйста. Пишем код.
$postvars = array(
"Email" => "mail(at)gmail.com",
"Passwd" => "pass",
"service" => "blogger"
);
$postdata = “”;
foreach ( $postvars as $key => $value )
$postdata .= “&”.rawurlencode($key).”=”.rawurlencode($value);
$postdata = substr( $postdata, 1 );
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, “https://www.google.com/accounts/ClientLogin”);
curl_setopt ($ch, CURLOPT_POST, 1);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $postdata);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec ($ch);
curl_close($ch);
echo $result;
В переменной $result у нас теперь находятся три строки, из которых нужна только одна — последняя, которая начинается с «Auth=». Но про это, наверное, в следующий раз.
Это кросспост из моего блога.
Избавляемся от ошибки ssl certificate problem – программирование и не только
При отправке запроса средствами cUrl вы можете получить следующую ошибку: «SSL certificate problem:unable toget local issuer certificate«.
Можно просто отключить проверку SSL-сертификата. Например, вот так:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://sitkodenis.ru'); ... curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); $result = curl_exec($ch);
А более правильным решением будет добавление сертификата в доверенные. Например, скачать более свежую версию сертификата по адресу https://curl.haxx.se/ca/cacert.pem.
Далее в настройках файла php.ini проверить путь к данному файлу:
[curl] curl.cainfo = /path/to/downloaded/cacert.pem
Спасибо за внимание и до новых встреч.
Обходим проверку сертификата ssl

В этом кратком обзоре я хотел бы поделиться своим опытом, как отключить проверку SSL для тестовых сайтов, иначе говоря, как сделать HTTPS сайты доступными для тестирования на локальных машинах.
В современное время https протокол становится все популярней, у него масса плюсов и достоинств, что хорошо. Правда для разработчиков он может вызывать легкий дискомфорт в процессе тестирования.
Всем известно, что при посещении сайта у которого “временно” что-то случилось c сертификатом вы обнаружите предупреждение, которое показывается, если сертификат безопасности не является доверенным net::ERR_CERT_AUTHORITY_INVALID?
Привет онлайн-кинотеатрам
Все современные браузеры показывают сообщение об ошибке HSTS
Самый простой способ обхода данного запрета — это, разумеется, нажатие на вкладку “Дополнительные” и согласиться с Небезопасным режимом.

Но не во всех браузерах как оказывается, есть данная возможность. Так я столкнулся с данной проблемой в Chrome на Mac OS
Разработчики данной операционной системы настолько обеспокоены безопасностью пользователей, что даже убрали доступ в «Небезопасном режиме» к сайту, несмотря на то, что это сайт владельца устройства.
Ну что ж, поскольку, вести разработку в других, более сговорчивых браузерах было не комфортно, вот способы как обойти эту проблему:
— Все хромоподобные браузеры (Chrome, Opera, Edge …) могут открыть небезопасную веб страницу, если на английской раскладке клавиатуры набрать фразу:
thisisunsafe
прямо на данной веб странице. Это даст возможность работать с сайтом без оповещение об ошибке на момент текущей сессии браузера, пока вы не закроете вкладку Chrome.
— Если же вам предстоит более длительная работа с сайтом, то рекомендую для этих нужд создать отдельного тестового пользователя на рабочем столе и указать ему необходимы флаги.
Для Windows
C:Program Files (x86)GoogleChromeApplicationchrome.exe" --ignore-certificate-errors

Для Mac OS
/Applications/Google Chrome.app/Contents/MacOS/Google Chrome --ignore-certificate-errors --ignore-urlfetcher-cert-requests &> /dev/null
Achtung! Данные манипуляции необходимо выполнять с выключенным Chrome приложением, иначе чуда не произойдет.
Если вы оставите сертификат ненадежным, то некоторые вещи не будут работать. Например, кэширование полностью игнорируется для ненадежных сертификатов.
Браузер напомнит, что вы находитесь в небезопасном режиме. Поэтому крайне не рекомендуется шастать по злачным сайтам Интернета с такими правами доступами.

*Так же есть метод с добавлением сертификатов тестируемого сайта в конфиги браузера Настройки->Безопасность->Настроить сертификаты->Импорт… но мне он показался не продуктивным и очень муторным, поэтому не привожу
Надеюсь моя краткая статья кому-то пригодится при разработке и тестировании сайтов =)
