Securing key into Android app from decompilation and developers - java

I am working on a project which requires the secret key to be hidden somewhere in the Android app, so that it can't be taken out even after decompilation.
The requirement even states that the key should not be visible to the developer, that means it should be embedded into some pre-compiled library.
I have tried the following things:
Making Jar and obfuscating the jar, Which becomes unusable after that. And its useless method to work with Strings (it doesn't encrypt Strings).
Making C library and using that library(NDK). The strings can be easily read using linux commands. Example: '$ strings '.
I am trying to find out other ways by which this can be done.
Please help me with this. If you have any idea, please share. I would be more than obliged.
Thanks.

Anything that your app can do, can also be reverse engineered by a determined capable hacker, so don't expect some magic way to make this key perpetually secured.
If your goal is to supply an SDK that will be licensed to different developers, then the easy approach is to allocate a unique key for each developer, and let them take care of hiding it from hackers.
On the other hand, if I read your requirement literally, it is enough that the key string will not appear in plain text in the APK. The easy solution is to encode it. You can do something as easy as base64 encoding of the key, or as tricky as providing a C function that will calculate this key on the fly (so no traces of the key will appear in the output of strings).

It's a hard problem. You're fighting a battle against reverse engineering your application. There are tools that are build for this, notably DexGuard and Arxan. Arxan is really, really clever, but it will cost a lot more than a solution like DexGuard.

For aar and jar protection against decompilation you can use Quixxi. Of course the effort is about raising the overall protection as much as possible, impossible is nothing. But this solution joins the best of both the points you made. What happens is the following conversion:
input: unprotected jar file
output: java file calling the native layer
You [or the developer that will need to manage the app containing your library] can later integrate it as described in the same link. Moreover the entire app can be protected with the same tool if other parts of it will need to be secured

Related

Is getClass().getHash() secure to use as a API key/password?

I'm looking for a way to generate a key on my app to connect to an API on my server, in the past users have decompiled the app and found the key, but with this method they can see how I generate the key but can't generate themselves the same key.
But still not sure if it is safe to use:
getClass().getHash();
Along with HTTPS it should be safe or am I missing something?
No, it's not secure. If one can decompile your code, then he/she can always retrieve any stored or computed information, even if obfuscation takes place (it would be harder to spot it, but again one can dig more and find it).
Check this similar post suggesting Jasypt or some other practices to use/store passwords in your projects.
There is still no safe solution to store credentials, as a successful decompilation can always retrieve it. You could ask from a user to type a password on each run and temporarily keep it on memory, but it seems you are interested in keeping this information secret even from your legitimate users. Also, if you use a client cert, then one could copy/reuse it in another instance of your program.
One could even utilize embedded devices (eg smart cards), where you need advanced hardware intervention knowledge and tools to extract private keys/passwords. But again, you need a sophisticated protocol (eg combining MAC/IP), as an advanced hacker could perform a replay attack (copy/paste/share the encrypted output of the smartcard), so he can use it on another run instance.
That's why there is still software piracy out there! Find a working solution and you'll get rich!

Decompiling a jar file and modifying the source to hack an application. How to prevent this? [duplicate]

How can I package my Java application into an executable jar that cannot be decompiled (for example , by Jadclipse)?
You can't. If the JRE can run it, an application can de-compile it.
The best you can hope for is to make it very hard to read (replace all symbols with combinations of 'l' and '1' and 'O' and '0', put in lots of useless code and so on). You'd be surprised how unreadable you can make code, even with a relatively dumb translation tool.
This is called obfuscation and, while not perfect, it's sometimes adequate.
Remember, you can't stop the determined hacker any more than the determined burglar. What you're trying to do is make things very hard for the casual attacker. When presented with the symbols O001l1ll10O, O001llll10O, OO01l1ll10O, O0Ol11ll10O and O001l1ll1OO, and code that doesn't seem to do anything useful, most people will just give up.
First you can't avoid people reverse engineering your code. The JVM bytecode has to be plain to be executed and there are several programs to reverse engineer it (same applies to .NET CLR). You can only make it more and more difficult to raise the barrier (i.e. cost) to see and understand your code.
Usual way is to obfuscate the source with some tool. Classes, methods and fields are renamed throughout the codebase, even with invalid identifiers if you choose to, making the code next to impossible to comprehend. I had good results with JODE in the past. After obfuscating use a decompiler to see what your code looks like...
Next to obfuscation you can encrypt your class files (all but a small starter class) with some method and use a custom class loader to decrypt them. Unfortunately the class loader class can't be encrypted itself, so people might figure out the decryption algorithm by reading the decompiled code of your class loader. But the window to attack your code got smaller. Again this does not prevent people from seeing your code, just makes it harder for the casual attacker.
You could also try to convert the Java application to some windows EXE which would hide the clue that it's Java at all (to some degree) or really compile into machine code, depending on your need of JVM features. (I did not try this.)
GCJ is a free tool that can compile to either bytecode or native code. Keeping in mind, that does sort of defeat the purpose of Java.
A little late I know, but the answer is no.
Even if you write in C and compile to native code, there are dissasemblers / debuggers which will allow people to step through your code. Granted - debugging optimized code without symbolic information is a pain - but it can be done, I've had to do it on occasion.
There are steps that you can take to make this harder - e.g. on windows you can call the IsDebuggerPresent API in a loop to see if somebody is debugging your process, and if yes and it is a release build - terminate the process. Of course a sufficiently determined attacker could intercept your call to IsDebuggerPresent and always return false.
There are a whole variety of techniques that have cropped up - people who want to protect something and people who are out to crack it wide open, it is a veritable arms race! Once you go down this path - you will have to constantly keep updating/upgrading your defenses, there is no stopping.
This not my practical solution but , here i think good collection or resource and tutorials for making it happen to highest level of satisfaction.
A suggestion from this website (oracle community)
(clean way), Obfuscate your code, there are many open source and free
obfuscator tools, here is a simple list of them : [Open source
obfuscators list] .
These tools make your code unreadable( though still you can decompile
it) by changing names. this is the most common way to protect your
code.
2.(Not so clean way) If you have a specific target platform (like windows) or you can have different versions for different platforms,
you can write a sophisticated part of your algorithms in a low level
language like C (which is very hard to decompile and understand) and
use it as a native library in you java application. it is not clean,
because many of us use java for it's cross-platform abilities, and
this method fades that ability.
and this one below a step by step follow :
ProtectYourJavaCode
Enjoy!
Keep your solutions added we need this more.

My Java GUI interfaces with my uber-cool proprietary dll. How can I prevent 3rd parties from interfacing with this dll?

I'm writing my process in C++.
Now I want to write its GUI.
I was thinking of using Java in order to do this and link it using JNI, but then I thought of a security problem...
Suppose I have my GUI.exe file written in Java, and I also have my Engine.dll file written in c++.
What would prevent evil evil people from taking my DLL and linking it to their program?
I do use a license validation stuff in my C++ dll, but it can be broken by these evil evil people.
I know every program can be cracked, but I don't want to just GIVE them my engine for easy use.
Is there a way to secure this link?
Or should I use C++ for writing the GUI as well?
The most portable solution probably involves encrypting the data entering and leaving your DLL by whatever means seems appropriate. Obfuscation of the C++ side isn't necessary at that point. This would require the encryption keys to be embedded in both the C++ binary and whatever you are compiling your Java to; you could take extra steps to make this inconvenient to find by hiding it with a large slab of random junk and indexing into it, for example.
Another alternative is to pay up for a licensing system that would be checked at call or link time by ubercool.dll.
Ultimately you're trying to perform a bit of a doomed defensive action. If your ubercool function is genuinely valuable or useful and someone wants to use it in ways you'd rather they didn't, they'll work out how. Can anyone think of any commerical software that hasn't been cracked?
Lastly, you can run your software on a system which is impractical for the end user to fiddle with. Mobile devices with locked bootloaders, TPM modules and so on are one way to do this; the other is to run your ubercool stuff as a hosted service to which people may connect if they have appropriate credentials which you can of course control.
Consider using obfuscator for your Java or C# code that will use your dll. This will not solve all the problem, but it will be more difficult to reverse engineere your programm.
Also, if your project is written in C++, you may consider using C++\CLI for your GUI part of application.

Customizable Java application Ideas

So I am working on a java application, and the customer has requested the ability to have features that which can be unlocked to make the application customizable based upon what their customer wants to pay for. So I am trying to come with ideas for doing this in a manner that will provide some level of security, but also general maintainability and readability.
I have been doing some searching around, and had some ideas of my own, maintaining an encrypted configuration file which could possibly be stored in a jar file that I could unload, repack, and load at run time.
Looking to see if anyone else has any interesting ideas on how you might do this. I have been doing some looking on google without a lot of success thus far.
Oh one last little caveat, the machines this java application is on may not have internet available to them. So running a license server doesn't seem like a viable option
I would suggest using some sort of dependency injection or runtime weaving aspects, so you can include new jar files that have the correct xml files or configuration files for new features.
I agree with coobird that including them and locking them is inherently risky as someone will eventually decompile your application and determine how to get all the features.
The only sure way to prevent "unauthorized access" to features that are "locked" in software is not to provide the code that one does not want the user to have access to in the first place.
Enabling extra features by unlocking using passwords, encryption (where's the key going to be? In the program itself?), configuration file can usually be defeated by someone who is determined to get to the code they want to execute.
At least unlocking using software means can most likely be defeated, if the code that is locked is already being distributed in the binary. One way that I can think of off the top of my head that seems a little secure is an hardware key dongle, or having important code that is stored on hardware, but not many people like the idea of having to plug in a piece of hardware to use the software.
When it really comes down to it, don't have features in the code itself which is only disabled by some software flags.
I suggest you build a trusting relationship with your customers. Either that, or bundle a USB key dongle, but even these are not 100%.
If you are distributing software, any kind of encryption must be able to decrypt itself. You are essentially giving the customer both the lock and the key.
You could possibly implement the core product, and then have the additional features as plugins. You could put each plugin in a separate jar file. The customer could then distribute a bundle that contained the core application, and the purchased plugins. Thus the un-purchased functionality is not in any of the binaries.
Distribute the full set. Have them call you for the keys to unlock various features. (Use a simple encryption scheme so that the keys are of reasonable length and can be conveyed over the phone.)

Creating non-reverse-engineerable Java programs

Is there a way to deploy a Java program in a format that is not reverse-engineerable?
I know how to convert my application into an executable JAR file, but I want to make sure that the code cannot be reverse engineered, or at least, not easily.
Obfuscation of the source code doesn't count... it makes it harder to understand the code, but does not hide it.
A related question is How to lock compiled Java classes to prevent decompilation?
Once I've completed the program, I would still have access to the original source, so maintaining the application would not be the problem. If the application is distributed, I would not want any of the users to be able to decompile it. Obfuscation does not achieve this as the users would still be able to decompile it, and while they would have difficulty following the action flows, they would be able to see the code, and potentially take information out of it.
What I'm concerned about is if there is any information in the code relating to remote access. There is a host to which the application connects using a user-id and password provided by the user. Is there a way to hide the host's address from the user, if that address is located inside the source code?
The short answer is "No, it does not exist".
Reverse engineering is a process that does not imply to look at the code at all. It's basically trying to understand the underlying mechanisms and then mimic them. For example, that's how JScript appears from MS labs, by copying Netscape's JavaScript behavior, without having access to the code. The copy was so perfect that even the bugs were copied.
You could obfuscate your JAR file with YGuard. It doesn't obfuscate your source code, but the compiled classes, so there is no problem about maintaining the code later.
If you want to hide some string, you could encrypt it, making it harder to get it through looking at the source code (it is even better if you obfuscate the JAR file).
If you know which platforms you are targeting, get something that compiles your Java into native code, such as Excelsior JET or GCJ.
Short of that, you're never going to be able to hide the source code, since the user always has your bytecode and can Jad it.
You're writing in a language that has introspection as part of the core language. It generates .class files whose specifications are widely known (thus enabling other vendors to produce clean-room implementations of Java compilers and interpreters).
This means there are publicly-available decompilers. All it takes is a few Google searches, and you have some Java code that does the same thing as yours. Just without the comments, and some of the variable names (but the function names stay the same).
Really, obfuscation is about all you can get (though the decompiled code will already be slightly obfuscated) without going to C or some other fully-compiled language, anyway.
Don't use an interpreted language? What are you trying to protect anyway? If it's valuable enough, anything can be reverse engineered. The chances of someone caring enough to reverse engineer most projects is minimal. Obfuscation provides at least a minimal hurdle.
Ensure that your intellectual property (IP) is protected via other mechanisms. Particularly for security code, it's important that people be able to inspect implementations, so that the security is in the algorithm, not in the source.
I'm tempted to ask why you'd want to do this, but I'll leave that alone...
The problem I see is that the JVM, like the CLR, needs to be able to intrepert you code in order to JIT compile and run it. You can make it more "complex" but given that the spec for bytecode is rather well documented, and exists at a much higher level than something like the x86 assembler spec, it's unlikely you can "hide" the process-flow, since it's got to be there for the program to work in the first place.
Make it into a web service. Then you are the only one that can see the source code.
It can't be done.
Anything that can be compiled can be de-compiled. The very best you can do is obfuscate the hell out of it.
That being said, there is some interesting stuff happening in Quantum Cryptography. Essentially, any attempt to read the message changes it. I don't know if this could be applied to source code or not.
Even if you compile the code into native machine language, there are all sorts of programs that let you essentially decompile it into assembly language and follow the process flow (OlyDbg, IDA Pro).
It can not be done. This is not a Java problem. Any language that can be compiled can be decompiled for Java, it's just easier.
You are trying to show somebody a picture without actually showing them. It is not possible. You also can not hide your host even if you hide at the application level. Someone can still grap it via Wireshark or any other network sniffer.
As someone said above, reverse engineering could always decompile your executable. The only way to protect your source code(or algorithm) is not to distribute your executable.
separate your application into a server code and a client app, hide the important part of your algorithm in your server code and run it in a cloud server, just distribute the client code which works only as a data getter and senter.
By this even your client code is decompiled. You are not losing anything.
But for sure this will decrease the performance and user convenience.
I think this may not be the answer you are looking for, but just to raise different idea of protecting source code.
With anything interpreted at some point it has to be processed "in the clear". The string would show up clear as day once the code is run through JAD. You could deploy an encryption key with your app or do a basic ceasar cipher to encrypt the host connect info and decrypt at runtime...
But at some point during processing the host connection information must be put in the clear in order for your app to connect to the host...
So you could statically hide it, but you can't hide it during runtime if they running a debugger
This is impossible. The CPU will have to execute your program, i.e. your program must be in a format that a CPU can understand. CPUs are much dumber than humans. Ergo, if a CPU can understand your program, a human can.
Having concerns about concealing the code, I'd run ProGuard anyway.

Categories

Resources