Why we cannot have perfect encryption and why we can't trust anybody
Something that has only really dawned on me recently through the whole NSA spying issue and what they (and possibly others) can and can't know about me from the internet traffic I create and consume. Part of my job is writing software that is secure so people can trust it so I am very interested in what I can achieve in terms of security in my software and possibly in other products that I could produce. Let's be honest, there is much money to be made in good security products so why not? This led me to my first question that set off a whole chain of events.
1) How is my data secure from snooping?
Firstly, I use SSL for all communication links but we know SSL fails in various areas. Firstly there are a couple of known exploits Beast Attack and RC4 attacks possibly the most famous or at least the most famous of the ones that are possible even on newer implementations of TLS/SSL. This brings up another important issue, "Use TLS 1.2" they all say but we cannot. Quite simply, too many end-users are still using older browsers that don't support it and amazingly, even some new browsers do not support it out of the box: Browser support. If we are honest, many of these attacks are highly unlikely but TLS/SSL is still potentially insecure.
Secondly, what about the ciphers I use, both in TLS/SSL and also for the data itself? Well, everyone knows AES256 is amazingly hard to crack (or do we?) but what about the ciphers used in SSL. Again, a very sloppy organic growth of SSL and the need to support the widest range of web servers and browsers/clients means a frightening amount of cipher suites are possible during an SSL handshake, the web server supports a set, the browser supports a set and they negotiate which to use (my guess would be the first to match regardless of any type of ordering). The only way to reduce these is to use newer versions of TLS and browsers but again, that is not possible for public sites that want to support everyone. Even more frightening, is a classic man-in-the-middle attack that intercepts the cipher negotiation and tells both ends to use the weakest protocols it has in order to make interception and decryption much easier.
We can't really trust SSL as it stands. And back to AES256, I only trust it because that is the common consensus, I don't personally know whether it is solid, I do not know whether large governments have ways to make the cracking easier, I do not know whether specific implementations have back-doors into them put there by corporations, hackers, governments or anyone else. And Open Source? Great in some ways but how many people are really watching all the commits and spotting exploits that have been inserted by someone or other?
2) If I assume my SSL and my AES256 is secure in itself, how secure is the key?
Well, many people say that encryption should be secure if everything about it is known apart from the key. It's a bit like letting people examine the door to the vault and assuming that any weaknesses will be pointed out (they could be seen but not pointed out!) but if someone has the key, it is game over. This is part of the motivation for cryptographic hashing but this just opens other problems instead.
So how can we use our symmetric key? Well two options, we generate one using a key generator or we stretch a password to create the key dynamically. Both of these, of course, move the key problem to a storage problem.
Assuming the key generator and the password stretching algorithm are sound (again, most of us can never know this - it is easier to know something isn't true than to prove it is) the key itself or the password used to create it need to be stored somewhere. Database? Lots of ways in which that can be accessed, particularly with Cloud Computing, often you are sharing a database server which means that someone (not you) has a Super Admin account and could access ANY data in your database. If you are using a Cloud Service DO NOT store keys in a database.
We could store it on disk somewhere but again, if the storage is shared, other people potentially have access, another client perhaps (by mistake) a dodgy sys admin like Edward Snowden who (rightly or wrongly) abuses his access privileges or indeed a company who accidentally or purposely allow governments to access this data for "legitimate reasons". The problem with keys is they cannot be encrypted, otherwise you need another key which cannot be encrypted, eventually it is stored somewhere "in the clear".
The question is, what can you use to secure your keys? Servers and many higher-end modern PCs have a hardware security module which allows, theoretically, secure storage of keys in a way that cannot be obtained by reading hard disks or whatever but these are, of course, designed more to protect against stolen computers. Malware running in software is still able to obtain these keys in the same way the system obviously needs to access them. Again, can we trust the corporations not to put back doors in? Can we trust them not to make a mistake in the design which allows access to them? Do we know that governments cannot remotely login to our servers and get these keys?
In Cloud Computing systems, keys are stored in the infrastructure. Again, of course, we have no idea how these are stored and whether they are secure. If I use encryption in my Azure system and the key is the SSL certificate I uploaded to Azure (and told it the private key password) do I really know that this is secure? Of course not. The system does need access to these keys to share them amongst web instances for TLS/SSL connections but at the same time, anyone in the world could have gained access to my system and I wouldn't even know.
Conclusion
So what? Clearly, we are a long way from this Utopian idea that encryption can buy us the privacy some people so eagerly desire. I have nothing to hide in one sense but I also do not relish the idea of armies of complete strangers analyzing my digital footprint to find out about me.
Before everyone says we need to go back to the old days, remember that trust has always been an issue and I suspect always will. Chelsea Manning was trusted with US secrets and blow the whistle, the same for Edward Snowden and I'm sure many others we will never know so the idea that the communication system/storage is the only risk is, in itself, flawed. While we need to communicate with someone else, there is always the chance that the other person is the security hole.
That being said, there are some things we can do to help protect ourselves but only to a point.
1) How is my data secure from snooping?
Firstly, I use SSL for all communication links but we know SSL fails in various areas. Firstly there are a couple of known exploits Beast Attack and RC4 attacks possibly the most famous or at least the most famous of the ones that are possible even on newer implementations of TLS/SSL. This brings up another important issue, "Use TLS 1.2" they all say but we cannot. Quite simply, too many end-users are still using older browsers that don't support it and amazingly, even some new browsers do not support it out of the box: Browser support. If we are honest, many of these attacks are highly unlikely but TLS/SSL is still potentially insecure.
Secondly, what about the ciphers I use, both in TLS/SSL and also for the data itself? Well, everyone knows AES256 is amazingly hard to crack (or do we?) but what about the ciphers used in SSL. Again, a very sloppy organic growth of SSL and the need to support the widest range of web servers and browsers/clients means a frightening amount of cipher suites are possible during an SSL handshake, the web server supports a set, the browser supports a set and they negotiate which to use (my guess would be the first to match regardless of any type of ordering). The only way to reduce these is to use newer versions of TLS and browsers but again, that is not possible for public sites that want to support everyone. Even more frightening, is a classic man-in-the-middle attack that intercepts the cipher negotiation and tells both ends to use the weakest protocols it has in order to make interception and decryption much easier.
We can't really trust SSL as it stands. And back to AES256, I only trust it because that is the common consensus, I don't personally know whether it is solid, I do not know whether large governments have ways to make the cracking easier, I do not know whether specific implementations have back-doors into them put there by corporations, hackers, governments or anyone else. And Open Source? Great in some ways but how many people are really watching all the commits and spotting exploits that have been inserted by someone or other?
2) If I assume my SSL and my AES256 is secure in itself, how secure is the key?
Well, many people say that encryption should be secure if everything about it is known apart from the key. It's a bit like letting people examine the door to the vault and assuming that any weaknesses will be pointed out (they could be seen but not pointed out!) but if someone has the key, it is game over. This is part of the motivation for cryptographic hashing but this just opens other problems instead.
So how can we use our symmetric key? Well two options, we generate one using a key generator or we stretch a password to create the key dynamically. Both of these, of course, move the key problem to a storage problem.
Assuming the key generator and the password stretching algorithm are sound (again, most of us can never know this - it is easier to know something isn't true than to prove it is) the key itself or the password used to create it need to be stored somewhere. Database? Lots of ways in which that can be accessed, particularly with Cloud Computing, often you are sharing a database server which means that someone (not you) has a Super Admin account and could access ANY data in your database. If you are using a Cloud Service DO NOT store keys in a database.
We could store it on disk somewhere but again, if the storage is shared, other people potentially have access, another client perhaps (by mistake) a dodgy sys admin like Edward Snowden who (rightly or wrongly) abuses his access privileges or indeed a company who accidentally or purposely allow governments to access this data for "legitimate reasons". The problem with keys is they cannot be encrypted, otherwise you need another key which cannot be encrypted, eventually it is stored somewhere "in the clear".
The question is, what can you use to secure your keys? Servers and many higher-end modern PCs have a hardware security module which allows, theoretically, secure storage of keys in a way that cannot be obtained by reading hard disks or whatever but these are, of course, designed more to protect against stolen computers. Malware running in software is still able to obtain these keys in the same way the system obviously needs to access them. Again, can we trust the corporations not to put back doors in? Can we trust them not to make a mistake in the design which allows access to them? Do we know that governments cannot remotely login to our servers and get these keys?
In Cloud Computing systems, keys are stored in the infrastructure. Again, of course, we have no idea how these are stored and whether they are secure. If I use encryption in my Azure system and the key is the SSL certificate I uploaded to Azure (and told it the private key password) do I really know that this is secure? Of course not. The system does need access to these keys to share them amongst web instances for TLS/SSL connections but at the same time, anyone in the world could have gained access to my system and I wouldn't even know.
Conclusion
So what? Clearly, we are a long way from this Utopian idea that encryption can buy us the privacy some people so eagerly desire. I have nothing to hide in one sense but I also do not relish the idea of armies of complete strangers analyzing my digital footprint to find out about me.
Before everyone says we need to go back to the old days, remember that trust has always been an issue and I suspect always will. Chelsea Manning was trusted with US secrets and blow the whistle, the same for Edward Snowden and I'm sure many others we will never know so the idea that the communication system/storage is the only risk is, in itself, flawed. While we need to communicate with someone else, there is always the chance that the other person is the security hole.
That being said, there are some things we can do to help protect ourselves but only to a point.
- Know where your security risks are and the level of risk. For instance, if you are relying on TLS/SSL to protect communications, that is reasonable but record it somewhere so that if this was ever broken badly, you would immediately know where you are exposed. Sadly, I suspect most people have never done a basic risk analysis of their system.
- Stick with the most widely regarded patterns and modes of encryption and update regularly. For instance, why are people still using MD5 for password hashing? Also, understand why you choose these things, why is bcrypt probably better than SHA-256 for password hashing (because it is deliberately slow)
- Never, never, never invent your own crypto-systems, ciphers, key derivation functions etc. unless they go through peer review. Just because MD5(data) + MD5(data) seems like it will be twice as strong doesn't mean it is! The people who write these things are either stupidly clever or they take a LOT of time and effort and research to ensure they are solid.
- Think twice before using shared hosting servers if you are selling a security product. You can still use a data centre but if the machines are yours, you know what is on them and you know, to an extent, that they are not accessible by people who shouldn't be accessing them.
- Linux servers are more likely to be secure to back-door remote access than windows but I think if Windows really did have it, people would know by now with the various pen-test tools available.
- Rotate keys over time so that if a key was obtained, the chances of being able to decrypt older or newer data is reduced, also, the attacker would need to steal the key and the data at the same time.
- Be very aware of social attacks (possibly the most common attack vector) and the amount of access people have to your systems. If you are a startup, does the sales director really need access to your code just because they are on the same network? Just by doing very basic access controls, you could prevent many attacks.
- Don't base your entire business case on the fact you can trust any system. Even modern "browser based" encryption systems that promise the earth are mostly quite weak due to weaknesses in the design of JavaScript and browsers (for all the same reasons as before).