Sometimes, it is useful to hide a string from a binary (executable) file. For example, it makes sense to hide encryption keys from binaries.
When I say “hide”, I mean making strings harder to find in the compiled binary.
For example, this code:
const char* encryptionKey = "My strong encryption key";
// Using the key
after compilation produces an executable file with the following in its data section:
4D 79 20 73 74 72 6F 6E-67 20 65 6E 63 72 79 70 |My strong encryp|
74 69 6F 6E 20 6B 65 79 |tion key |
You can see that our secret string can be easily found and/or modified.
I could hide the string…
char encryptionKey[30];
int n = 0;
encryptionKey[n++] = 'M';
encryptionKey[n++] = 'y';
encryptionKey[n++] = ' ';
encryptionKey[n++] = 's';
encryptionKey[n++] = 't';
encryptionKey[n++] = 'r';
encryptionKey[n++] = 'o';
encryptionKey[n++] = 'n';
encryptionKey[n++] = 'g';
encryptionKey[n++] = ' ';
encryptionKey[n++] = 'e';
encryptionKey[n++] = 'n';
encryptionKey[n++] = 'c';
encryptionKey[n++] = 'r';
encryptionKey[n++] = 'y';
encryptionKey[n++] = 'p';
encryptionKey[n++] = 't';
encryptionKey[n++] = 'i';
encryptionKey[n++] = 'o';
encryptionKey[n++] = 'n';
encryptionKey[n++] = ' ';
encryptionKey[n++] = 'k';
encryptionKey[n++] = 'e';
encryptionKey[n++] = 'y';
…but it's not a nice method. Any better ideas?
PS: I know that merely hiding secrets doesn't work against a determined attacker, but it's much better than nothing…
Also, I know about assymetric encryption, but it's not acceptable in this case. I am refactoring an existing appication which uses Blowfish encryption and passes encrypted data to the server (the server decrypts the data with the same key).
I can't change the encryption algorithm because I need to provide backward compatibility. I can't even change the encryption key.
Here's a perl script to generate obfuscated c-code to hide a plaintext password from "strings" program.
For C check this out: https://github.com/mafonya/c_hide_strings
For C++ this:
In order to use this, just include Alpha and:
So mystr is "Test" now and the string is hidden from strings table in binary.
I think you want to make it look like instructions, your example of
x[y++]='M'; x[y++]='y'; ...
Would do just that, the long sequence of repeated instructions with a little variation may stand out and that would be bad, the byte in question may get encoded in the instruction as is and that would be bad, so perhaps the xor method, and perhaps some other tricks to make that long section of code not stand out, some dummy function calls perhaps. Depends on your processor as well, ARM for example it is real easy to look at binary data and pick out the instructions from the data and from there (if you are looking for a default key) to possibly pick out what might be the key because it is data but is not ascii and attack that. Likewise a block of similar instructions with the immediate field varying, even if you have the compiler xor the data with a constant.
I was once in a similarly awkward position. I had data that needed to be in the binary but not in plain text. My solution was to encrypt the data using a very simple scheme that made it look like the rest of the program. I encrypted it by writing a program that took a string, converted all the characters to the ASCII code (padded with zeros as necessary to get a three digit number) and then added a random digit to the beginning and the end of the 3 digit code. Thus each character of the string was represented by 5 characters (all numbers) in the encrypted string. I pasted that string into the application as a constant and then when I needed to use the string, I decrypted and stored the result in a variable just long enough to do what I needed to.
So to use your example, "My strong encryption key" becomes "207719121310329211541116181145111157110071030703283101101109309926114151216611289116161056811109110470321510787101511213". Then when you need your encryption key, decode it but undoing the process.
It's certainly not bulletproof but I wasn't aiming for that.
Hiding passwords in your code is security by obscurity. This is harmful because makes you think you have some level of protection, when in fact you have very little. If something is worth securing, it is worth securing properly.
Actually, in a lot of situations nothing is better than weak security. At least you know exactly where you stand. You don't need to be a "real hacker" to circumvent an embedded password ...
EDIT: Responding to this comment:
If you care about security at all, maintaining backwards compatibility is a REALLY BAD reason to leave yourself vulnerable with embedded passwords. It is a GOOD THING to break backwards compatibility with an insecure security scheme.
It is like when the street kids discover that you leave your front door key under the mat, but you keep doing it because grandpa expects to find it there.
The technology of encryption is strong enough to secure important data without hiding it in a binary file.
Or is your idea to use a binary file to disguise the fact that something is hidden?
That would be called steganography.