Mobile Apps use HTTP. But they usually don’t use it to transfer HyperText – rather they are using it to transfer JSON, XML, or other data formats. Just like their web counterparts, secure transmission is desirable.
But, if you ever trace a fresh SSL connection, you know that its a nasty process:
- TCP handshake
- SSL handshake
- Server sends certificate
- DNS to CA
- TCP to CA
- OCSP to CA
- Finish SSL handshake
- Finally do what you wanted to do….
SSL is designed so that you can pick up some random certificate and check it dynamically. This is a good thing for the web, where the user coasts from site to site, happily discovering new content which needs new validation.
But this process is pretty costly, especially on mobile networks. For my own service, I just did a quick trace over 3G:
- DNS (1334ms)
- TCP handshake (240ms)
- SSL handshake (376ms)
- Follow certificate chain (1011ms) — server should have bundled this.
- DNS to CA (300ms)
- TCP to CA (407ms)
- OCSP to CA #1 (598ms) — StartSSL CA uses connection close on each!
- TCP to CA #2 (317ms)
- OCSP to CA #2 (444ms)
- Finish SSL handshake (1270ms)
With the web, this verification process makes some sense – you ask the CA to be your trust point and verify that he trusts the certificate provided.
But why do this with a mobile app? Your mobile app has a lot of trust with it – they downloaded it from you, its signed by Apple, and if the code has been compromised, well, heck, your app isn’t really running anyway.
What we really want for mobile apps is to bake the server’s certificate into the app. If the server’s certificate needs to change, you can auto-update your app. In the example above, doing so would have shaved about 3000ms off application startup time.
The downside of this is that if your certificate changes, your app won’t verify. Then what to do? Simple – force an auto update.
There is another advantage to this approach. If you can verify your own certs, you don’t need a CA provided certificate anyway. These silly 1-2 year expirations are no longer necessary. Sign your own cert, and verify it yourself. Since our CAs have been getting hacked left and right in 2011, this is probably even more secure.
PS: SSL is hard. In this one trace, I can spot at *least* 3 low-hanging-fruit optimizations. I haven’t mentioned them, because they are pervasive everywhere on the net. There are errors here at every level – the client is missing opportunities, the server is missing opportunities, and the CA is missing opportunities! It’s no wonder that SSL is slow. The chance that your combination of client + server + CA will have some dumb performance bug is ~99%.
2 thoughts on “Rethinking SSL for Mobile Apps”
Except in the case of certificate expiry, the only reason you would want to change your certificate is in the case of private key loss, private key compromise, or a need to change the certs subject.
The scary one here is private key compromise. This is why the client checks the OCSP or CRL, before finishing the handshake. This is vital. In your auto-update scenario, if the private key is compromised, then the attacker can also compromise your auto-update, assuming that it is initiated from within your app. In the compromise scenario, I certainly wouldn’t want to wait on some app store to notify the user about an update and hope they take it in a timely fashion. The OCSP or CRL is a wonderful cut-off switch. Put the cart before the horse once, and you may never be able to get it back in place.
Certainly beware of the risk you take if you go without revocation checking prior to completing the handshake.
As a side note, most SSL connection setups have the option to turn off revocation checking. This gets you the faster handshake and doesn’t burden you with managing your own CA. That is usually a recipe for disaster, unless you are a PKI lover.
BTW how do you trace the mobile connection. If it is from your computer you can use a Wireshark kind of tool. How do you trace your mobile connection?