JavaFX Application - What needs to be signed? - java

I'm deploying a JavaFX application and am not quite sure what does and doesn't need to be signed. Here are my thoughts:
- Installation file:
This obviously needs to be signed.
- The EXE that launches the application:
I believe this needs to be signed, although it feels a little bit funny because it isn't my code.
- My JAR files: I believe that these also need to be signed, although I'm not sure if anything terrible happens if I don't.
- Library JARs that I've grabbed off the internet: I don't feel like I should sign these. Is there any reason to?
- Java runtime:
I'm guessing there's no reason to sign this, and I'd probably violate some agreement if I do.
- JNLP file:
Not using this, no reason to touch this.
Have I looked at this properly? Am I signing the correct files?

A friend of mine has a saying " it's not what you did... it's what you can prove in court. "
With this respect, I advise you to look at this problem from a legal point of view and assume the worst possible context it can apply in; i.e. you becoming legally accountable after someone tampers with your software.
Digital signatures are designed especially for these types of problems.
With this respect, let's split your answer into 2 different classification parts:
the software you're releasing - includes your jars, jnlp, bundled .exes, etc.
all of these must be singed in order to ensure that you can't be affected by any unauthorized tempering with your own code. It doesn't matter whether or not you've released that jnlp. If someone generates an invasive one and it's traced back to you, your failure to authenticate your own released version of that jnlp will not be ok.
the software released by other people. - includes everything which you're using in order to get your system to work. (jre, libs)
when using something like this, it's a good idea to make sure you're using a genuine copy of whatever your lib manufacturer has released. Use their checksums/signatures/etc. to validate and verify their software integrity upon demand. You have to read their liability and disclaimer statements and in the event they fail to provide one themselves.
In general it is a good idea to place as little trust as possible when it comes to software sources other than yourself. Unfortunately, there are many compromised or malicious libs out there which are in fact security risks.
it is always a good idea to make sure you're releasing a downloaded lib which is certified by an external issuer and as such cannot be held responsible for any malicious code detected within.
To answer your question... it really depends on the client endpoint and the likelyhood of you getting sued for providing them with a security risk (i advise you to always expect this to be 100%). If you're liable for damages... you need to proceed accordingly.
In short... the best possible answer to this quesiton is to do whatever is possible to cover yourself in the event the worst happens.

Does your application need elevated privileges? If the installer is targeting Windows you wish to install the application to Program Files, then your installer will need to be signed. Without it, Windows will give a yellow banner during privilege escalation request.
So - sign your installer.
The exe that launches the application should ideally be signed as well. But for a java application, this is perhaps a mute point. Signing the exe is easy enough, that I'd just do it anyways.
Sign launcher exe - Optional, but I'd do it
Jar files. This is an interesting one and depends on what you goal is. Ie, the OS and the end user are probably not going to be aware of the signed or unsigned nature of your Jar. Therefore you will probably have to verify the integrity of the jar yourself. See https://docs.oracle.com/javase/tutorial/deployment/jar/signindex.html
Perhaps the launcher application can perform the integrity checks before the launch step ?
Library jars, Similar to the case above, if you want to make sure that no one has dropped in a diff jar into your application or some such use case, you will need to verify this yourself.
Java Runtime If you shipping this, is this not already signed by Oracle or your JVM vendor ?

Related

Safe distribution of Spring based application

Im thinking about creating spring boot application that i would like to comercialize some day.
I planned to build a Jar that i would allow to download, and once client launched it locally and provided some license key, it becomes useable.
I have some doubts about this distribution strategy especially in the meaning of the safety of the code and licensing.
If i provided a Jar, anybody may try reverse engeenering on it - so its easy to be hacked or cracked.
Turning it into executable is more user friendly, also possibly may hide the code better, but still i think its relatively easy to be reverse engineered.
It made me think about obfuscation. If i completely messed up the app before prod build, it would be a way harder to understand or change the code. It may seem okay in the matter of "copying and modifying" the app, but still i think it would be easy to locate licensing limitations in the source files. For example: limit for 5 users can be easilly located in sources by value "5" or the message the user sees, and even if code looks awfull, this lines can be removed, project compiled again, breaking the limitation and wasting my entire effort.
It will be small application, I want to provide clients the instalator, and let them set it up personally. I dont want to be responsible for settting it up in the cloud for the client (without publishing instalator or Jar), as clients may not be interested in cloud based access.
Could You advise me some wise solution for this situaltion?
Thanks in Advance ! :)
The short answer is that there is no way to prevent reverse engineering if someone can run the software on hardware that they control.
The only way to 100% prevent reverse engineering is to ONLY run the software on a platform that you control ... and that can prevent them from getting a copy of the executables.
There are a couple of ways that can make reverse engineering harder:
Use an obfuscator on your JAR files. It will make it harder for someone to read the decompiled code. There are 3rd-party obfuscator products you could use.
Use jpackage (or a 3rd-party tool) to create a native executable for your application.
But beware that modifying an application to disable a license check is much simpler than full reverse engineering. A determined software engineer (or hacker) will be able to do that, given enough time and incentive.
Look at this problem another way:
There are many people and companies making money out of writing and supporting software without resorting to license keys, obfuscation and so on.
Conversely, there are probably millions of aspiring software entrepreneurs who never even turn their clever idea into a worthwhile (saleable) product.
Conversely, there are millions of apps (e.g. in Android app stores) that are simply not worth the effort protecting from IP theft.
Don't get lost in the problem protecting your IP before you have actually created it. And don't overrate its (hypothetical) value.

When to sign the JAR files? [duplicate]

Why should I sign my JAR files?
I know that I need to sign my client-side JAR files (containing Applets) so that special things like filesystem access can be done, and so that the annoying bit at the bottom of windows doesn't show, but why else? And do I need to sign my server-side JAR files containing Servlets, etc.?
Some basic rules for when and when not to sign JARs would be appreciated - thanks!
The short answer - don't, unless your company policy forces you to.
The long answer
Signing jars is effectively telling your customer "I made this, and I guarantee it won't mess up your system. If it does, come to me for retribution". This is why signed jars in client-side solution deployed from remote servers (applets / webstart) enjoy higher privileges than non-signed solutions do.
On server-side solutions, where you don't have to to placate the JVM security demands, this guarantee is only for your customer peace of mind.
The bad thing about signed jars is that they load slower than unsigned jars. How much slower? it's CPU-bound, but I've noticed more than a 100% increase in loading time. Also, patches are harder (you have to re-sign the jar), class-patches are impossible (all classes in a single package must have the same signature source) and splitting jars becomes a chore. Not to mention your build process is longer, and that proper certificates cost money (self-signed is next to useless).
So, unless your company policy forces you to, don't sign jars on the server side, and keep common jars in signed and non-signed versions (signed go to the client-side deployment, non-signed go to server-side codebase).
Signing a jar file, just like using certificates in other contexts, is done so that people using it know where it came from. People may trust that Chris Carruthers isn't going to write malicious code, and so they're willing to allow your applet access to their file system. The signature gives them some guarantee that the jar really was created by you, and not by an impostor or someone they don't trust.
In the case of server-side or library jars, there's usually no need to provide that kind of guarantee to anybody. If it's your server, then you know what jars you're using and where they came from, and you probably trust your own code not to be malicious.
A good reason could be if you never wanted anybody to be able to sneak in modfied classes to be called by your code.
Unfortunately that includes yourself :-D So this is only to be done if you really need it. Check the "sealed jar" concept.
In terms of applets: From 6u10, the Sun JRE replace the warning banner with less obtrusive (from 6u12, IIRC) warning triangle (necessary to support shaped and transparent windows). 6u10 also allows controlled file access through the JNLP services API.
The principle of least privilege says that you should not sign the classes of your jar files. Security is not necessarily easy.
Simply showing a certificate dialog box should not be construed to mean that the entire contents of a web page is to be trusted.

Encrypting a JAR where source protection is a priority

I have a dilemma. Basically, I've given a group of people I'm friends with a program that utilizes source code that I don't want anyone outside the group knowing of. We all know Java is absolutely horrible at doing any level of obfuscation, as most obfuscation tools only rename objects, scramble code, etc. I've used such tools, but to be honest I'd like to go as far as possible with the security of the program.
Since the application requires a username, password, and other identifiers to log in to the server it uses, I was beginning to wonder if a unique AES key could be generated for the user to secure the JAR.
Basically, upon running a launcher of sorts to log in, the launcher app may request an AES key from the server, and use it to decrypt a secured JAR it's downloaded from the server already. The key would be completely unique to each user, which would mean the server would have to encrypt the JAR differently for each user.
Now, I know how crazy this sounds. But since this is such a low-level thing, I need to know if there is a way you can somehow both decrypt and run a JAR from any type of stream. Or, if that isn't possible, would it be reasonable to decrypt the file, run it, then re-encrypt it?
Of course you can decrypt and run Java bytecode on the fly - bytecode manipulation libraries such as ASM even go as far as creating new classes dynamically.
But, quite honestly, if something actually runs on a computer then its code is definitely going to be available to anyone with the knowledge. Java, especially, is even more convenient since it allows far better access to the bytecode of a class that is loaded by the JVM than any natively compiled language.
You could theoretically take your obfuscation a bit further by using JNA/JNI and a native shared library or two. But, in the hands of a determined attacker no measure will protect your code completely - it would just take more time for them to figure out how your algorithms work. And if you are concerned about piracy, well, we are in the era of virtualization; you can actually clone whole computer systems from top to bottom with a couple of key presses - you figure out the rest...
The only potentially viable solution would be to offer your software as a service, with all the issues entailed by that approach - and you would still not have absolute security.
If you are that concerned about protecting your intellectual property, then get a lawyer and consider publishing your algorithms in some form - obscurity will only go so far. It will not stop someone from doing black-box analysis on your system and quite often just knowing that something is possible is enough.
Please stop trying to find technical solutions to a problem that is so obviously not of a technical nature...
My answer would be to keep the server information outside of the jar entirely. Use a parameter or configuration file to point to where to get that information. Then the jar file has no secrets in it. Only the server where the code runs has that information. You can then do things like make the configuration file readable only by the user that can run the code in the jar.

Is it OK to modify rt.jar?

I'm creating an application that launches the JVM (using a copy of the JRE). If I edit rt.jar, for example to remove functionality that users shouldn't have access to, will it somehow break the JRE?
EDIT: The application involves downloading code onto a user's machine, so it would be restricting the code rather than the user. I probably should have clarified that.
There's a good chance you would break something that won't be noticeable until runtime.
But perhaps more important is the licensing problem: your app is shipping its own version of the JRE, which you're allowed to do, except you cannot modify the JRE you're distributing, as per the J2SE license:
[...]
(a) you distribute the Software complete and unmodified and only
bundled as part of Your applets and applications ("Programs"),
It's also questionable what is meant by "to remove functionality that users shouldn't have access to". Your application is executing in the context of a user account, and whatever functionality you removed from the JRE:
If the OS allows that particular action in the context of that user's session, then there's another way to do it - hence you're in the same position you were in before messing with rt.jar. Your user can just make a system call.
If the OS doesn't allow that action in the context of the user's session, then the JVM won't be able to do it either, whether the classes are present or not, so the whole question is moot.
Usually, the best way to remove functionality is to use a SecurityManager. This allows you to control what can be accessed or key action can be performed.
Completely depends on what you "remove". But its possible. As long as you dont break anything, remove dependencies etc...
And if you want to do something security wise. How can you ensure that you and only you have full control over the users JRE?
And if this is the case. What benefit would your doing do what you can't do in your application?
But its possible and a valid thought for some reasons. But they are mostly benchmarking, developing, debugging. For example dumping unencrypted bytecode
Also be aware of the licensing problem. You probably won't be legally able to sell or ship this.
why do you ask, you might potentially break some agreement/license, other than that it's ok.
I don't do so that but change the bootstrap loader's classpath to load my classes before rt.jar, etc. This is legal :)
In the end: Getting NoClassDefFoundError aint cool, no matter how you look at it.
If you're asking if it's legally okay, I don't know but chances are that it isn't. (If you're intending to sell your product, that is. For research or recreational uses it probably is.)
Is it okay technically? If you know what you're doing, it can be.
Does it make sense though? How hard it is for the client to install another VM or just replace your hacked rt.jar with an unhacked one?
And on a more abstract level: is it a good idea to treat your customers like potential criminals? To assume that the first thing they're going to try is to hack your system. (Mind you, I don't know your customers, so you might as well be right, but the question is worth asking nevertheless.)

How to deliver a java program to a client?

I wrote a software application in Java. Now I want to deliver it to my clients. But before that, I want to do something on that software which are mentioned below. You can answer any or all of the below questions:
I want to:
Encrypt all the .class files so that no one can decompile it. How can I encrypt it?
After encryption I want to obfuscate that code to add extra safety. How can I do that?
Add some "serial-key" functionality so that the software works only after registering it with the key provided by me. This is very important so as to prevent multi-user usage of my software. How can I add that key functionality and how can I generate keys. And how can I restrict that software to work only on a single computer.
The jar file can be unzipped and the .class file can be seen. Is there any way to wrap jar file into something so that no one can unzip that file.
I don't want to tell the client to first install java to run my application. So is there any way by which if anyone installs my software, the java automatically gets installed on his/her computer without informing him that java is being installed to his computer. If it is possible, then Is it legal to use Java software in this way.
Change the icon of the jar file permanently.
Implement a code which checks my site for any available updates.
If you want any other suggestions to increase the security of the softwre, then you are welcomed too.
In no particular order:
2 - There are products that perform obfuscation. They typically rename classes / variables / methods to single letter names. This makes determining user reported errors rather difficult. Stack traces showing the exception occurs in a.b.c are not particularly helpful.
1,3,4 - You can't fully avoid this risk if your are distributing java. Your code needs to be unpacked and loaded at some point. If someone replaces rt.jar in the jvm then they can replace the top-level class loader and dump out your classes like that. Obfuscation makes this less useful for them, but see the above caveat.
5 - Distribute a "private jre". Basically, you have a jre in your program folder. Your launcher script runs it. Increases the size of your distribution though.
6 - On windows, this would be a file association issue. But that would also affect all other jar files. Unless as part of 4 (however you manage that) you also use a different extension. Not sure about other operating systems.
7 - Use Java Web Start? Failing that, just have a file on your server listing the most recent version, fetch the file and compare with the installed version.
For 1,2,4 and 5 you could also look into compiling to native code using gcj or similar. Beware of compatibility issues if you do that though.
Encrypt all the .class files so that no one can decompile it. How can
I encrypt it?
You can't. If no one can decompile it, how do you expect the target JVM to?
After encryption I want to obfuscate that code to add extra
safety. How can I do that?
I want to add some "serial-key"
functionality so that the software
works only after registering it with
the key provided by me. This is very
important so as to prevent multi-user
usage of my software. How can I add
that key functionality and how can I
generate keys. And how can I restrict
that software to work only on a single
computer.
There are a couple of ways to do this but a simple one is with public key cryptography:
Your software generates a random request ID or a request ID based on the machine attributes and your user submits this to you.
You sign the request ID with your private key and send it back to the user.
The user provides the signed request ID to the software which validates that it was signed by you.
The jar file can be unzipped and the .class file can be seen. Is there
any way to wrap jar file into
something so that no one can unzip
that file.
No
I don't want to tell the client to first install java to run my
application. So is there any way by
which if anyone installs my software,
the java automatically gets installed
on his/her computer without informing
him that java is being downloaded to
his computer. If it is possible, then
Is it legal to use Java software in
this way.
Try building an NSIS installer for your application that detects/installs Java and your program.
Build a better trust relationship with your clients.
Then you can spend extra time ( not doing tasks 1-5 ) to make improvements, fix bugs, etc., which in turn improves relationship with your clients.
You can compile it with GCJ, which will compile your application to a normal Windows/Linux native executable (.exe). Then you can create an installation, using a program like InstallShield.
The company where I work actually ships unobfuscated jar files, with all debug information in place. That way, if an error occurs at a client's site, they can send us the full stacktrace which helps enormously in analyzing and localizing bugs in the code.
Trying to obfuscate your code will lead you into an arms race with potential crackers and consume huge amounts of time with little or no real benefit. Instead, I'd advise you to try and find other ways to make buying (and not pirating) your software worthwhile to your clients. For example, you could offer them free updates, or tech support, or something like that.
As for 6: You can use JSmooth or a similar tool to create an exe wrapper for your app. It will allow you to change the icon, and your clients will have an exe file that they can doubleclick without having to mess with file associations for jar files.
Note, however, that the generated exe won't contain Java or your jar files. It will, however, print a nice error message if Java isn't available.
Just adding on to the other answers here:
1 and 4: You could actually do this if you modify the JVM and pre-package it with your installation, but it's against Java's license agreement to distribute a modified JVM without paying Sun like a billion dollars.
Who is your client? Piratebay.org? Seriously, every major company in the US pays for software. The risk of a client quitting and calling them in is just too high. You need enough protection to make it easier for a programmer to get purchasing to pay for the product than to circumvent your copy protection.

Categories