5

Is there a way to save a static password in a way that it's really hard to find in the compiled app?

There's two different apps I need that for. One is a lightweight FTP client for Windows that only connects to one hard-coded server. The other is an Objective C game that lets users create level packs and use passwords to save them. They can be played without password, but not opened in the level editor. I'm encrypting the passwords with AES, but I have to somehow save the password for decryption.

The only idea I've found so far is saving the password not as one string, but as multiple strings. This could work really well for the game because I could just connect strings that are already there. Or I could save it as a long string and use a secret algorithm to get the password out of that string - although that begs the question: can C apps on Windows or Cocoa apps on OS X simply be decompiled to find that algorithm?

Are there more secure ways to do that?

JasonMArcher
  • 14,195
  • 22
  • 56
  • 52
Alex Wally
  • 2,299
  • 1
  • 20
  • 18
  • I guess a really simplistic way that's still effective against basic resource inspection is to save the password string XOR'd with a number (saved separately). Then XOR it with the same number to 'decrypt'. This wouldn't hold up to serious attempts at decompiling, nor memory inspection, especially if you store the decoded string in memory for any length of time. – Bob Mar 28 '12 at 16:35
  • 3
    http://en.wikipedia.org/wiki/Security_through_obscurity – Oliver Salzburg Mar 28 '12 at 17:00
  • That (security through obscurity) is the category of things like putting different strings together or XORing them with numbers, right? I think I'll just XOR some strings, and use words that don't sound like a password if someone is actively looking for one. I don't wanna put too much thought into it, because it looks like every encryption can be broken if the attacker has the app on their own system. Thanks a lot for the hints though, like not keeping the decoded string in memory for too long :) – Alex Wally Mar 28 '12 at 17:26
  • @Alex as you cannot store the key safely I would advise *against* using real crypto as looking for the encryption method would quickly find your key and encrypted password. XOR is used enough to sneak under the radar, making it (slightly) harder to find the obfuscated string. – Maarten Bodewes Mar 28 '12 at 20:10
  • @Alex Please post that as an answer and mark it as accepted. :) – Ben Richards Mar 28 '12 at 20:26
  • @owlstead wait, why would I not use real crypto? People can make a Chosen Plaintext attack, so I'm not sure if I should just XOR everything. – Alex Wally Mar 28 '12 at 20:53
  • @sidran32: Stack Overflow doesn't allow me to self-answer yet, so I'll do it tomorrow. (Since I'm in Germany, it's late enough to go to bed now.) – Alex Wally Mar 28 '12 at 20:56
  • As said, because the method call to "cipher.doEncrypt()" would be pretty easy to find within the application. XOR on the other hand is a machine instruction that is used everywhere in the code. As you don't have a secure store somewhere to store the key in (if you would, you *should* use real encryption) the password would be pretty easy to find. That said, finding the method call to login to ftp would be easy as well. – Maarten Bodewes Mar 28 '12 at 21:13
  • 1
    I hope your security doesn't depend on your users not figuring out this password - because it's inevitable that they will if they care enough, regardless of what steps you take to obfuscate it. – Nick Johnson Mar 29 '12 at 09:30
  • @NickJohnson I'm gonna try to avoid the FTP app, because it's too insecure for me. As for the game, I reckon I'll just tell people not to use their bank password, because it can be broken if someone really wants to. - Oh, or use a hash there, because that encryption doesn't have to be reversible. – Alex Wally Mar 29 '12 at 15:29
  • @owlstead I guess it's a tradeoff - passwords can either easily be cracked by chosen plaintext attacks, or if I'm using a secure algorithm, by looking for the encryption function within the application. – Alex Wally Mar 29 '12 at 15:29

3 Answers3

2

can C apps on Windows or Cocoa apps on OS X simply be decompiled to find that algorithm?

Yes, all made by human can be broken by another human. Never use reversible algorithms for storing sensitible data - they will be reverse-engineered. You can store hashes, as sidran32 wrote, but it doesn't help you with client

Lazy Badger
  • 94,711
  • 9
  • 78
  • 110
2

Why go through the pain of decompiling - a simple

$strings <binary>

will do it :) Storing your passwords in the code is never going to work: you can split them, encode them, encrypt them any way you like - there will be a point when you need to reassemble the parts in order to verify them. And that's exactly the point where an attacker will hook into, probably with a debugger. I gave an answer to a similar question with more details.

The only really secure way is to store the passwords as out-of-band information, outside your code (or the binary for that matter). These kinds of DRM that you have in mind never work for a longer period of time, as millions of cracked Microsoft or other products prove.

Community
  • 1
  • 1
emboss
  • 38,880
  • 7
  • 101
  • 108
  • I knew about the strings command, but I figured if I chose a password that doesn't look like a password, people would never find it. How does it work with a debugger? Could you just find the string in memory, even if I release it immediately? - Also, as I said, I realize that if someone really wanted to find the level codes, they could - I mean, *all* encryptions can be broken with enough effort. I'm just looking for a solution that will make it not worth the bother. – Alex Wally Mar 29 '12 at 15:34
  • @Alex As you can inject `__asm{int 3};` calls into the disassembly of any executable, or even just simply break into the run somehow, the attacker could have the program sit, essentially paused, at any point in the program flow. If the string exists in memory in completed form at all at any point, it is vulnerable, even if you release it quickly. And, even if it's released, the string will remain in memory until the program (or another) writes over that memory location. That's what he's referring to. – Ben Richards Mar 30 '12 at 01:06
  • Oh, okay - I didn't know that. So in any case, the password could be found in what, 10 seconds? - I wonder if it could help to somehow use the file contents (i.e. the level, which is not secret) and use a secret algorithm to turn it into a password. – Alex Wally Mar 30 '12 at 09:37
  • No, the problem is that whenever someone has physical access to the machine you are basically screwed. They can monitor the memory and whatever you come up with, at some point it will end up in memory. Even if you try to clear the memory immediately after use, there is always a window of opportunity - you make it harder with such measures, but it is still possible. – emboss Mar 30 '12 at 10:17
-2

String literals are usually retained and stored somewhere in the binary even in compiled C source.

What you could do is a similar method to how (properly implemented) web apps validate login information where that info is stored in a database. Just store the password in hashed form. Often, the method is to use MD5 + salt (here is a description and some sample PHP code). What you can do is instead of transmitting or storing the plaintext password, just hash the user input and check the hash against the stored hash value. Matching hashes corresponds to matching passwords.

EDIT

This won't help with the FTP server case though, since you cannot modify its source code...

Ben Richards
  • 528
  • 5
  • 14
  • Thanks for the answer. That could work for the password in the game, but not for the FTP app or for level codes, which I didn't even mention yet. My bad :) – Alex Wally Mar 28 '12 at 17:23
  • Modded down, as for FTP you would either use the hash as password, which would amount to plain text, or the password itself, and hashing is one way... – Maarten Bodewes Mar 28 '12 at 20:08
  • Makes no sense. Hashing doesn't help here. – CodesInChaos Mar 28 '12 at 20:11
  • @CodeInChaos Hashing would be useful if he had access to the FTP server's source code for its password validation implementation, but he doesn't. I didn't address that case, as I missed that requirement in my answer... – Ben Richards Mar 28 '12 at 20:22
  • @sidran32 And how would it be useful in that case? That doesn't help you hide the password on the client in any way, you've just redefined what you understand by "password". The OPs problem is that what he wants can't really be done. – CodesInChaos Mar 28 '12 at 20:31
  • @CodeInChaos I (mis)understood that he'd be storing the password to check against. – Ben Richards Mar 29 '12 at 00:08
  • I'll just accept this answer because it's closest to a perfect answer. – Alex Wally Mar 29 '12 at 22:37