LooInSpain Posted March 20, 2017 Share Posted March 20, 2017 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? Quote Link to comment Share on other sites More sharing options...
requinix Posted March 20, 2017 Share Posted March 20, 2017 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). Client: 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. Server: 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. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted March 20, 2017 Share Posted March 20, 2017 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”. Quote Link to comment Share on other sites More sharing options...
requinix Posted March 20, 2017 Share Posted March 20, 2017 (edited) 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 March 20, 2017 by requinix Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted March 20, 2017 Share Posted March 20, 2017 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. Quote Link to comment Share on other sites More sharing options...
LooInSpain Posted March 20, 2017 Author Share Posted March 20, 2017 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. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted March 20, 2017 Share Posted March 20, 2017 I've come up with a different method which should be enough for them. What method? Quote Link to comment Share on other sites More sharing options...
LooInSpain Posted March 20, 2017 Author Share Posted March 20, 2017 What method? An encrypted username / password along with an openssl public private key combination. Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted March 20, 2017 Share Posted March 20, 2017 This doesn't make any sense whatsoever. Do you actually want to provide a good solution for the client, or do you just want to throw buzzwords around, get paid and call it a day? Quote Link to comment Share on other sites More sharing options...
LooInSpain Posted March 20, 2017 Author Share Posted March 20, 2017 What would you suggest then? Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted March 20, 2017 Share Posted March 20, 2017 What I said in #5: a strong API key. Quote Link to comment Share on other sites More sharing options...
LooInSpain Posted March 20, 2017 Author Share Posted March 20, 2017 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 Quote Link to comment Share on other sites More sharing options...
Jacques1 Posted March 20, 2017 Share Posted March 20, 2017 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. Quote Link to comment Share on other sites More sharing options...
requinix Posted March 20, 2017 Share Posted March 20, 2017 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. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.