iossecurityinterceptionconfidentiality

Cryptographic Keys exchange between client and server


I have seen many examples on verifying client or server certificates using Security framework APIs but this will solve only problem of Identification of security features but what about Confidentiality of data? How do I exchange private and public keys between client and server? What about Interception, Modifications, or Fabrication attacks? What if someone pretending and sending correct certificate as expected by client?


Solution

  • Identification is provided by verifying the cert as you note. Confidentiality is provided via encryption. Authentication is provided by signing the data. Together they are often implemented via TLS over a network connection.

    In short, if you properly implement and deploy HTTPS, and validate your certificates, then you will get all of the things you're describing. NSURLConnection will do almost all of this for you by default if you just use an "https" URL.


    If you deploy a certificate on the server and protect its private key, then it is not feasible for an attacker to pretend to have that certificate. Only the server has the server's private key (it is up to you to protect the private key from copying or theft).

    A typical approach is to use a commercial certificate, in which a certificate authority (CA) like Verisign attests that the private key was issued to the owner of a given host (known as the CN or common name). This is a simple-to-use approach and generally cost effective. Go to one of the well-known CAs and buy a cert.

    However, you can also create your own public/private server keypair, protect the private key, and distribute the public key in your client. You can then configure your client to only accept that one certificate and no others. This is actually more secure than the commercial certificate. For an example of this, see SelfCert. This is from my CocoaConf-RTP-2012 talk. I'll be giving a similar talk at CocoaConf-DC-2013. It is also discussed at length in chapter 15 of iOS:PTL.

    Client certificates are less common. They are used to authenticate the client, not the server. For a client certificate to work correctly, each client must have its own certificate. You can't ship a private key as part of your bundle. If you do, anyone can use that private key to impersonate a client. (Conversely, it is completely fine to put the server's public key in the bundle. It's public; you don't care who sees it.)

    With CFNetwork, after connecting, you would need to use CFReadStreamCopyProperty to fetch the kCFStreamPropertySSLPeerTrust. You could then evaluate the returned SecTrust object. That said, I recommend the NSURLConnection code if you can use it. If you need lower-level access, you could still use NSStream. Jeff Lamarche discusses this in NSStream: TCP and SSL. But I'd recommend a tool like AFNetworking or CocoaAsyncSocket instead if you need lower-level control over TCP+SSL.