I'm currently writing a server-client secure architecture, an alternative to using HTTPS APIs that should work particularly well with mobile apps.
You acquire apps from a store (a trustworthy source) so you can assume that data hasn't been tampered with. Hence you can include with the app files a server certificate and a fallback certificate, and you can use that to securely authenticate with the server.
I'm trying to keep the overhead far lower than TLS (currently, for session resumption only ~210 bytes need to be exchanged for a functional connection), and alleviate the financial burden of TLS certificates (you pay the cost of secure delivery to the store, anyway). RESTful APIs should be pretty straightforward to translate to this model.
Apps today use HTTPS for secure calls to the API, and I think it's highly unnecessary to have the overhead of certificate presentation, cipher negotiation, and even the HTTP header for what is often as few as 40 bytes of request/response data.
Currently the server seems to perform extraordinarily well: I'm running a PHP backend and have a request-response model, like HTTP does, and I'm working on optimizing it to the levels of lighttpd, because I know it's possible. My point is that a reasonably secure specialized protocol can be made more efficient than TLS, especially when you know what you are always connecting to.
You do realize that using TLS doesn't necessarily imply that you require the overhead of certificates and ciphersuite negotiation?[0]
Given how difficult implementing TLS securely already is, I'm highly skeptical that you will be able to come up with anything that's faster and more secure than TLS especially since it won't be receiving peer review from trained cryptographers.
Implementing TLS securely owes its difficulty partly to the variety of ciphersuites and optional features that all need to be securely implemented. Building a simpler protocol which suites some specialized needs will make the number of ways in which you can screw up considerably smaller.
The StackOverflow answer you are linking to suggest hardcoding the server public key in the client (as was my idea) and then throwing away the whole server certificate. This means that the server wastes its precious time to send an X.509 certificate which the client will essentially discard (and it will add to the packet size, too). My protocol is currently very similar to TLS_RSA_WITH_AES_128_CBC_SHA256 mentioned in the answer. I'm using RSA, AES-256 in CBC mode, and SHA-256 HMAC authentication. I'm thinking of maybe switching from AES-CBC+HMAC to AES-GCM, but modifications to the protocol won't be hard if I get everything up and running smoothly.
I am, too, highly skeptical that I will come up with anything that is both faster and more secure than TLS. That's why I am open-sourcing it and not even thinking about trying to profit from it. I'm doing this for my own satisfaction, and if that results in something that will help others, that would be even better.
I don't have a problem with using TLS for secure communication in the client-server API case, but also with stuffing HTTP up there. This requires people to run a web server that will serve the API calls, and I conjecture that there is non-trivial overhead of the call going through the HTTP layer and getting dispatched to a script interpreter. And the cost is twofold because the response must get back from the interpreter, to the HTTP layer, augmented with an ASCII header and sent back through the TLS layer to the client application.
As part of this, since the scripts on the server are PHP currently (but with an ability to change this fairly easily), I'm working on a more lightweight FastCGI alternative that sacrifices some of FastCGI's aspects (such as running the FastCGI daemon on one host and calling into the scripts from another) but dispatching a request to a PHP instance (which I keep preforked, with a couple of spare ones, much like Apache does for its own processes) is essentially a zero-overhead operation.
I'm trying to be as secure as I can, attempting to mitigate timing and other side-channel attacks as much as vulnerabilities in the protocol itself. That's why I'm reusing a lot of the TLS ideas, but working in my own down there. I'm going to try to get trained cryptographers to review both the protocol and the code, but I don't aim to provide any warranty.
I'm aiming to build a better solution not for TLS, but for secure HTTP RESTful APIs when the client can know server information beforehand. It's a lot narrower use case and I think I can tackle it more effectively, and if it turns out to be a dead end, I'll have some experience on my hands. And the server I'm building is highly modular, so some parts (especially the threadpooled libuv-based protocol-agnostic backend) may be reused later if deemed appropriate.
I have absolutely zero problems with experimentation, I like doing that as well.
My primary concern is with people (and I'm not claiming that you are one of them) publishing such experiments without huge "This should not be used in production!!!" warnings and some poor fool deploys it and gets pwned 3 months later.
TLS does have some overhead because of its flexibility, yes. But it's still incredibly fast and should not be a bottleneck in most scenarios. Given that it has been battle-tested with very little flaws found (most bugs are implementation bugs, not protocol bugs), it is and will be for the foreseeable future the #1 option for anyone looking for a encrypt-data-while-in-transit solution.
> Hence you can include with the app files a server certificate
For more flexibility, you can include your own CA certificate, which you use to sign your servers' certificate, so that you can add/remove them without needing to update the app.
> I think it's highly unnecessary to have the overhead of certificate presentation, cipher negotiation
If you (as a user) are really strict about privacy/security, or if you exchange a lot of information with the server, the benefits of TLS (or any security scheme for that matter) will outweigh the drawbacks soon enough that you will not think of it as a problem.
> what is often as few as 40 bytes
Your credit card number is only 16 bytes, but I guess you want to securely transmit that :)
>For more flexibility, you can include your own CA certificate
This would require the server to present a certificate to a client. With that, I might as well be creating a TLS clone. So I'd like to avoid that for the sake of simplicity, at least for the first versions. I'll see where it goes from there.
>If you (as a user) are really strict about privacy/security, or if you exchange a lot of information with the server, the benefits of TLS (or any security scheme for that matter) will outweigh the drawbacks soon enough that you will not think of it as a problem.
I was referring to cipher negotiation and certificate presentation, both of which, in my case, are in theory unnecessary to have security as strong as provided by TLS.
>Your credit card number is only 16 bytes, but I guess you want to securely transmit that :)
I never said I wanted to sacrifice security for the 40 bytes, I was just saying that the HTTP overhead and TLS overhead is really a lot, and if I can get away with a specialized protocol with a lower overhead, that would be even better :)
If you're not bothering with the HTTP protocol then you don't even need a certificate at all. You just need to have something like SSH's 'known_hosts' file. All you need to know when initiating communication over a secure channel is that the key the server sent you is in fact the key for the server. In fact, if you're including something with the app, just include the servers public key directly. Forget the whole key exchange process. Then use the server's public key to send a symmetric key generated by the app itself (sort of like TLS does) for the duration of the connection. This provides forward secrecy as well. Simple. Elegant. Secure.
The only catch is that if you change the server's key it will break all clients. However, you could always hard code a second public key that isn't even contained on your servers that is used as a fallback for catastrophic incidents where your private key gets exposed. Once you fix your security hole you swap out your key to your fallback and clients are secure again.
Actually, when I said 'certificate', I actually only meant the public key, that's basically what you were describing. I rely on RSA-OAEP to detect if someone's been trying something funny (I've been told on StackExchnage Crypto that I can rely on it to tell me if a message I'm decrypting was encrypted using a non-matching public key). However, sending a client-generated symmetric key using the server's public one is not perfectly forward-secret: namely, if a server's key ever gets compromised, prior recorded communication can be trivially decrypted. I want to minimize the damage done if a server key is exposed.
Furthermore, a compromised pseudorandom number generator on the client can compromise the security of communication. To mitigate that, at least partly, both parties in my scheme contribute half of a session AES key.
You're correct about the forward secrecy. That's what I get for commenting at 2am. I was thinking about TLS where there can be a frequently rotating asymmetric key pair. The symmetric key in TLS isn't used for PFS, only for performance. In practice those keys don't actually get rotated almost ever though.
Yes, sure, I'm thinking a BSD-like license. I'm using libuv for the event loop and sockets on the server and OpenSSL for cryptography. So far (besides the server and client running on Linux) I have a proof-of-concept client app for Android, but as soon as I get my hands on an iPhone or Windows Phone device, those ports will be done, too.
I wasn't. Thanks for the link. Besides the fact that it works on top of ZeroMQ and some differences in operation, it seems that it has roughly the same goals as me. Will look into the RFC for some ideas.
You acquire apps from a store (a trustworthy source) so you can assume that data hasn't been tampered with. Hence you can include with the app files a server certificate and a fallback certificate, and you can use that to securely authenticate with the server.
I'm trying to keep the overhead far lower than TLS (currently, for session resumption only ~210 bytes need to be exchanged for a functional connection), and alleviate the financial burden of TLS certificates (you pay the cost of secure delivery to the store, anyway). RESTful APIs should be pretty straightforward to translate to this model.
Apps today use HTTPS for secure calls to the API, and I think it's highly unnecessary to have the overhead of certificate presentation, cipher negotiation, and even the HTTP header for what is often as few as 40 bytes of request/response data.
Currently the server seems to perform extraordinarily well: I'm running a PHP backend and have a request-response model, like HTTP does, and I'm working on optimizing it to the levels of lighttpd, because I know it's possible. My point is that a reasonably secure specialized protocol can be made more efficient than TLS, especially when you know what you are always connecting to.