Another day, another rant about how developers underestimate potential crackers. While I actually wanted to write a review about developing on Mac OS X vs Windows, or the fresh install I did of Windows 8, once again I'm surprised by the naiveness of some developers when it concerns security measures in software.
Using encryption doesn't necessarily make your software more secure.
Let's assume you have communication between two applications using network sockets. You don't want to use ssl, but your own solution. This solution consists of encrypting certain traffic using AES and a secret key. Is this more secure than a ROT13? Well, not really. I compare such solutions with sticking a piece of tape to cover the hole of a lock. It might stall a cracker for a moment, but it's not a real deterrent. The security given by the encryption is imaginary.
"But they can't know the encryption method".
Well, even without looking at the code segment, it is still easy to find out the encryption method. Let's go over the possibilities of how the encryption code is linked:
- You use operating system provided methods.
- You use OpenSSL as a dynamic library.
- You use OpenSSL as a static library.
- You compile your own AES code.
For 1 and 2, a cracker can see which methods your exe links to, so that's very easy. For 3 and 4, a cracker doesn't need your obfuscated code, he can just search the data segment. For AES for example, you need the Rijndael S-box. This is a constant block of data which is easy to spot. So at this point we can agree that they know your method. (People using method 4 might be so smart to obfuscate their data of course).
"But they can't know the secret key".
From the data, they can look for code which uses the data (the calls that use offsets to that data). This code is eventually called from a place where you pass the secret key, which is also constant data. So all in all your secret key isn't that secret.
"But you can obfuscate the key".
True, but all those obfuscation methods can be read and copied, since the binary code is public knowledge.
"So encryption is useless?".
It is, unless a completely secure scheme is used. Using a known secret key is good if that key is external, For example when you encrypt a document, or a user needs to provide it each time. Using a secret key in your application however is not a smart thing to do. Instead use a key exchange mechanism like Diffie Hellman, and (in case of two user apps which can't be verified), a third party service to compare and make sure the shared secrets match and there's no man-in-the-middle (for more information on this see my previous post).
The cloud might be the best solution.
Even though some people believe in obfuscation tools, code will never become unreadable. A machine can read it, so a human with enough knowledge can too. The only possible solution to avoid giving away the code, but still let people use the application might be the cloud. If part of the application runs on the cloud, there's no use in trying to hack the client part. A document editor might allow a user to edit a document, but it is stored on a server, and exporting to desktop formats is also done on the server. Likewise with WebGL it is possible to build a 3D modeler, but the scene is stored on the server, and exporting or rendering is done there as will. While I'm not keen on storing my documents on a service which might disappear any moment, with a good sync to desktop capability I like this solution a lot more than schemes like UEFI Secure Boot.