2

I got a couple of licence keys from third-party vendor, these keys are authorized to my mobile application(C/C++ language), for not to be leaked to out world, the vendor need to review my code to ensure these keys are encrypted to prevent disassembling.

The initial way I got is encrypting(use reversible encrypt method) these keys and decrypting it while using, but this isn't the final solution, to be extreme, one can decrypt it to by reverse my code.

The vendor recommend using the reverse hash to encrypt these keys(I have no idea about reverse hash), is there any other choice(that simple, easy to implement but harder to disassemble) I can hide these keys in my code to prevent disassembling?

coanor
  • 3,746
  • 4
  • 50
  • 67
  • The vendor may have meant a **reversible hash** function? A normal hash is one-way: you can hash your strings, but it'll be damn hard to recover them from the result. – Edmund Apr 24 '12 at 03:36
  • Yes, I have Googled all the hash algorithms, no hash algorithm is reversible (or very-very hard to reverse), I do not know how to make it a `reverse hash` to get the solution... – coanor Apr 24 '12 at 03:44
  • @coanor Well, the point of hash algorithm is that they are irreversible, since almost any hash algorithm implies data loss. – Victor Vasiliev Apr 24 '12 at 05:53
  • If the vendor has a requirement that the keys be hidden to their satisfaction then surely they have some example code for how they might like you to do it? That way you won't have to guess whether or not it's "good enough" for them. – Michael Burr Apr 24 '12 at 06:23

3 Answers3

3

You can make reversing harder but you can't stop it. No matter what encrypting you choose a hacker can get the keys from your program because your program decrypts the keys for license checking.

Also a hacker can break the 3-rd party library instead of stealing your keys :)

I would ask the library vendor for code samples showing how to protect the keys to satisfy their requirements.

By the way there is a question about reversible hash on SO: Reversible hash function?

Community
  • 1
  • 1
Sergey Podobry
  • 7,101
  • 1
  • 41
  • 51
1

There is no such thing as a "reverse hash algorithm". Any hash algorithm is designed to be one-way and implies the loss of data. If it is two-way, it is called a cipher.

As long as user is able to run your application, and the application uses those keys at some point, the keys may be leaked. This can be done through disassembling and reverse engineering, through dumping the keys from memory, or through running a debugger. So the best thing you can do is to encrypt it somehow and make it as non-obvious to decrypt as possible.

Given that you are writing it for a mobile platform, you may try to rely on some OS mechanism to protect the keys. Or, if these are the keys for some web API, you may set up a server which stores those keys and work as a proxy. Or actually ask your third-party vendor about the best practices they have for protecting the keys and for specific implementation details like suggested encryption mechanism.

Victor Vasiliev
  • 462
  • 2
  • 12
1

Let's assume you'll have code like this:

unsigned char *bytes;
some_extremely_complicated_function_which_decrypt_key(bytes);
add_some_confusing_things();
maybe_even_split_into_several_calls(bytes);
// ...
call_function_using_their_key(bytes,data1,data2,data3);

Which will result into assembler looking like this:

push [ebp+0004h]  // data3
push ecx          // data2
push [ebp+0024h]  // data1
push [eax]        // key (bytes)
call 123456h      // call to call_function_using_their_key

You will almost always be able to get address of call_function_using_their_key from import/relocation table (unless it'll be inline, obfuscated really hard or few similar techniques).

I'd simply add automatically breakpoints to every call 123456h, last push = key, key pointing to memory address 543216h, get key from 543216h.

Any encryption was useless.

The moral of the story: first make sure that their API makes sense to encrypt data, otherwise you'll be good with this:

char *globalBytesPtr;

int main(){
    globalBytesPtr = malloc(N);
    globalBytesPtr[8] = 0x35;
    globalBytesPtr[3] = 0x14;
    globalBytesPtr[5] = 0x20;
    ...
}

Because with this your keys won't show up in static dump. This won't decrease security, because the weakest point is their API call and you cannot make application more safe in this universe.

Vyktor
  • 20,559
  • 6
  • 64
  • 96