Question

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?

Was it helpful?

Solution

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?

OTHER TIPS

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top