0

I need to create a client library to talk to a single service (say google.com) over HTTPS. I would like the library to ship with all data (a certificate or a key) needed to authenticate the service.

I'm confused what this data should be. Should it be a public key of a certificate authority that signed google.com certificate? Or should it be google.com public key?

In all examples I've seen, the certificate authority's public key is used to authenticate a connection. But it seems unnecessary. If my library talks only to google.com, can I obtain and save google.com public key over secure channel (a browser) and then use this key directly to establish authenticated connections without using CA key again?

Jan Wrobel
  • 6,969
  • 3
  • 37
  • 53
  • 2
    That's not how SSL works. You just need a trusted root CA so that you can verify the certificate that the server sends. – SLaks Jan 02 '13 at 18:20
  • @SLaks But my understanding was that CAs were introduced to allow to authenticate large number of sites without storing all their keys on the client side (management nightmare). If the library talks to a single server and has a public key of this server, is there still a need of certificate validation (if certificate is forged, the public key won't work anyway)? – Jan Wrobel Jan 02 '13 at 18:37
  • 1
    You're right; you can store a single public key and require that the server use that key. However, that makes it impossible to replace the key, which is why PKIs and CRLs exist. What would you do if the private key is compromised? – SLaks Jan 02 '13 at 18:39
  • @SLaks This is indeed a problem, if private key is compromised all clients need to be updated. But similarly, if CA key is compromised, or the server changes CA, all clients would need to be updated. This problem exists when a library ships with the smallest possible set off keys required to authenticate the server (often recommended approach). For example, Ruby HTTP library uses no default CA keys and the recommendation is to add as few keys as possible: http://stackoverflow.com/questions/9199660/why-is-ruby-unable-to-verify-an-ssl-certificate – Jan Wrobel Jan 02 '13 at 18:54
  • 1
    Hopefully, root CAs can employ better security measures than you can. http://en.wikipedia.org/wiki/Key_Ceremony – SLaks Jan 02 '13 at 18:57

1 Answers1

2

You need to use the server's key pair, not the CA. When establishing an HTTPS connection, data will be encrypted under the public key that gets presented. In order to decrypt that data, the server will need access to the corresponding private key, and it would be really bad if you had the CA's private key sitting around.

The purpose of the CA is so the client can validate the server's certificate through some trusted 3rd party. Your client will need the CA certificate to correctly authenticate the server, but presumably will already have and trust that CA.

Edit based on your comment:

There are more advantages to shipping the CA certificate instead of just the server certificate.

The primary reason is that in the event there is ever a compromise of the server's private key, you don't need to distribute new certificates to all your clients. Since the CA should be better protected than your server, the CA can simply issue a new certificate, which clients will trust without any extra work.

If you shipped your server's certificate, you'd need a way to securely update the certificate on every client.

mfanto
  • 14,168
  • 6
  • 51
  • 61
  • The question is not about the server but about the client. Why the client needs to be shipped with CA key to authenticate the server and can't be shipped directly with server's public key (that was obtained and validated with a browser)? – Jan Wrobel Jan 02 '13 at 18:28
  • Updated answer. If the CA is trusted, then you don't need to do anything special. It's also easier in the event on a compromise, since a CA is easier to protect and you won't have to update the client's with a new server certificate. – mfanto Jan 02 '13 at 18:38
  • Your answer contradicts itself after the edit, but he doesn't need to use *anybody's* key pair: he needs to use a *certificate,* which only contains a public key; and he should ship the certificate of the highest signer. The server's public key isn't used to encrypt anything in SSL, but it is used by the client to verify a signature generated by the server as proof that it owns that certificate. – user207421 Jan 02 '13 at 21:39
  • It doesn't contradict itself, I just might not have been clear on my wording. I'll clean it up. But the pre-master secret is encrypted under the server's public key during the handshake process. See Step 4 of http://publib.boulder.ibm.com/infocenter/wmqv6/v6r0/index.jsp?topic=%2Fcom.ibm.mq.csqzas.doc%2Fsy10660_.htm – mfanto Jan 02 '13 at 21:44
  • Apologizes, I got a little sloppy with 'key pair' in the course of the edits. – mfanto Jan 02 '13 at 21:51