Jump to content

PHP Certificate Authentication


Recommended Posts

I've been asked to create a data exchange between two servers. The client is hot on security and wants a high security handshake to confirm the identity before proceeding. Their advisor suggested a private / public key certificate to authenticate the transfer.

Exporting the data is fine. I've written many cURL scripts to send data to other servers using a public / private key system and I've already written the cURL for this system. The problem is handling the received certificate and authenticating it. I cannot find anything which relates to this type of transfer.

The cURL we will use to send data is

curl_setopt($ch, CURLOPT_SSLCERT, $certificate);
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $certificatePass);

My problem is how to request the certificate in the response php file and verify the private certificate with the public key. Can anyone help?

Link to comment
Share on other sites

The scheme you need is called X.509. You know how SSL/TLS uses a certificate on the server to verify identity? X.509 is the same thing but applied to both the client and server. You don't have to do any PHP to make this happen, depending how paranoid you want to be.


1. Create a certification authority; essentially a set of files (not a server) used to sign certificates. Like Verisign or Entrust or others, this authority acts as an entity that will be trusted by both parties to validate certificates. Creating your own means you can dedicate this authority to only signing certificates used in this exchange and simultaneously require that only certs signed by it are allowed; any ol' Verisign cert won't work. Back up those files somewhere safe: they're the keys to someone participating in this exchange.


2. Have the client and server generate their own certificates, then use the authority to sign them. Simply having a certificate proves the client is trustworthy, but you can also use the information in the cert to further confirm their identity (see #5).




3. Have cURL perform validation. This includes both verifying the server cert (against the custom authority) as well as providing the client cert from #2.




4a. Configure your web server with the server-side cert generated in #2. This is your standard SSL stuff. With Apache there are a handful of SSL* directives to enable this. Note that doing so means this HTTPS endpoint won't be easily browseable by a regular user: though it will have a cert and thus be secure, the browser will complain that the authority is not known/trusted. If this will be an issue then you should use a separate HTTPS endpoint away from the regular :443 one.


4b. Also configure it for client verification/X.509. A few more SSL* directives in Apache are relevant here too. This should involve indicating a trusting authority: that would be the one you did in #1. With this in place, the server will verify the client certificate against your authority, and only certificates signed by it should be permitted.


5. If you want to identify the client then it depends on your web server. Apache can set environment variables which will be available in $_SERVER; grab the email or DN or whatever from there and do what you want. Alternatively, you can have it pass the entire certificate and use PHP code to validate it manually (likely with openssl functions).


This looks like a good reference.

Link to comment
Share on other sites

This whole story doesn't add up.


What exactly is your job? Are you only doing the code? Are you supposed to be the sysadmin of the two servers? Are you supposed to create and maintain a PKI?


The shirt-sleeve let's-fumble-our-way-through-it approach may be OK if you want to secure, say, your personal blog. But it's downright dangerous when this is a professional environment where the client is “hot on security”.

Link to comment
Share on other sites

This whole story doesn't add up.

Sounds like client-speak: management got scared by something and wants to know that there aren't any l33t hackers watching their super-important traffic. And since Loo said "client" it sounds like a small- to medium-scale contracting thing.


If the advisor said "public/private key" then... well, that's not terribly helpful. Everything serious in security uses asymmetric keys nowadays. Given the technical context of Loo's post, I'd interpret it as doing something like using certs on both sides of the SSL socket - not a full-blown PKI infrastructure. But maybe we're talking about an unknown number of clients, in which case my solution would require some way to have the authority automatically sign certs without [much] developer involvement. Or on the other hand, maybe mere SSL would be enough to assuage fears.


Some more information about the nature of this system would be nice...

Edited by requinix
Link to comment
Share on other sites

I'd clarify a few things to avoid getting into trouble.


The proposed solution from the advisor is what? A specified goal everybody agrees on? A vague suggestion?


Setting up public-key authentication is complex, time-consuming and requires a well-maintained PKI behind it. Let's say one of the private keys gets compromised -- now what? You either need a revocation mechanism (like a CRL), or somebody has to do your job all over again. Both isn't very realistic in your case. A much more appropriate solution is to generate a long random API key, hash it on the target server (plain SHA-256 is fine in this case) and set up standard HTTPS.


If the client specifically wants public-key authentication regardless of the problems, fine. But I wouldn't implement it based on somebody-suggested-something.

Link to comment
Share on other sites

Thanks for all your replies and suggestions.


In all honesty I don't think it's worth going to all the trouble for this system as the data is not that sensitive.


Their website is hosted on a shared server for starters, so I think it's a non-starter. I've come up with a different method which should be enough for them.

Link to comment
Share on other sites

Thanks for your help Jaques,HTTPS isn't available on the clients server and not likely to be anytimes soon, so I'm gonna stick with a private key upload and checked with the public key on the target server. Alongside this will be a username and password encrypted with a constantly changing salt based on a number of variables.


Once again, thanks for your input and I'll be sure to remember this for any future projects of a similar nature

Link to comment
Share on other sites

HTTPS isn't available on the clients server and not likely to be anytimes soon [...]


And you tell us that now?


Yeah, so much for the super-secure public-key handshake kung fu. This project is BS, and as a developer, you should be able to see through the fancy buzzwords.




I'm gonna stick with a private key upload and checked with the public key on the target server.


Once again: This is nonsense. What you're saying doesn't even make sense.


Use an API key. If the client doesn't want HTTPS, they're obviously willing to take certain risks. So be it.


Inventing your own nonsense protocol isn't going to help anybody. Do what you can and be honest about it.

Link to comment
Share on other sites

None of this matters if you can't use HTTPS. You could have a 4096-bit rotating API key if you want, but if it's transported over plaintext HTTP then it's all pointless. No HTTPS is a deal breaker for having anything that could resemble security on this server. The fact that it's on shared hosting is already a sign that your client doesn't actually care about keeping their system safe.


Your job is now to call them on their bullshit.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.