Mihkel Allorg Mihkel Allorg - 1 year ago 103
PHP Question

Getting a ssl certificate ready for http request

I'll explain the situation.

Short version is that I have received a ssl certificate and I need to include it in some HTTP requests. And I haven't managed to correctly do it.

I'm using Guzzle to make the requests.

I have received the certificate as a string starting with


and ending with


First of all I'm not 100% sure, what do I have to do with it in order for it to be ready to be included in the request. I saved it as a
file. As the Guzzle docs mentioned they need a .pem file, I looked into converting .crt file to .pem file. Found this stackoverflow thread, tried them both and it didn't work (btw the .crt and .pem contents are identical). Let me explain, what did not work.

I made a

$client = new GuzzleHttp\Client(['base_uri' => 'https://theuri.com']);
$client->request('GET', 'getit', ['cert' => 'path/to/mycert.pem' ]);

The result was

cURL error 35: error:14094410:SSL routines:SSL3_READ_BYTES:sslv3 alert handshake failure (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)

I read that it's some standard error, when you've messed something up in the whole process of making a request with a certificate.

I also have private.key file and request.csr which were used in creating the SSL key. Not sure if I have to do anything with these now.

I have not found much helpful information online. The threads or articles that I have found have not explained the whole process from start to end so I haven't been confident in any of the methods I've tried.


I've found out that I should probably be using

$client->request('GET', '/getit', ['verify' => 'path/to/mycert.pem'])

It gives me the exception

GuzzleHttp\Exception\ConnectException with message 'cURL error 35: SSL peer handshake failed, the server most likely requires a client certificate to connect (see http://curl.haxx.se/libcurl/c/libcurl-errors.html)'

If I do it with 'cert', it's saying it can't load the certificate and its private key. I doubt that using 'cert' is the way to go.

Answer Source

Okay I've figured this out now. I hadn't had any experience with certificates before. I did it all on OS X but you should get the picture. Some things like adding a private key to your keychain is probably different.

  1. Generate a PKCS#12 certificate file

To do that, you need the certificate itself and the private key, which goes with it. In terminal you can do it with the openssl command. The full command is

openssl pkcs12 -export -clcerts -inkey ~/private.key -in ~/certificate.crt -out MyCertPKCS12.p12 -name "Full Name"

Now you've created a file MyCertPKCS12.p12 that you have to add to your Keychain and include with http requests. The file goes with a password and you will be asked to enter it once your run this command.

  1. Add PKCS#12 file to your Keychain

Opened Keychain Access and imported the .p12 file. At first had some trust issues and had to manually set the which components trust the certificate. To do that, open Keychain Access. Top left corners is a list of Keychains, select System and you will see your freshly added certificate there. Double click it to open and you can set what trusts this certificate from there.

  1. Making a http request with the certificate

First if you have to do a simple GET request, you can type the url into your browser and you should be asked if you allow using a certificate. Allow it and select the certificate. Everything should work now. If not, google the error message.

Doing a GuzzleHttp request with the certificate goes as following:

$client = new GuzzleHttp\Client(['base_uri' => 'https://muchsecure.wow']);
$cert = "/path/to/MyCertPKCS12.p12";
$method = "GET"; //or whatever the method is
$response = $client->request($method, '/getinfo', ['cert' => [
     $cert, 'epicpasswordISetForTheP12File'

And now you've made a request to url https://muchsecure.wow/getinfo with the certificate.

If you have any more questions I'll be happy to help you all.