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.
Related
I am new to certification in java.Just on another post just now,I found out that it is not possible to use jarsigner on java apps,its only used for applets.Could anyone confirm this?
Next I would like to know,what is the common way people developers give thier apps to the clients,I mean do they not put any certificate for it?I mean a year or six months certificate.
This I am talking is with respect to a normal java app not an applet
UPDATE
This is what I tried:I jarsigned my app yesterday and gave the validity of 1 day,today when I saw it never got expired.So thats why I was wondering if it is only for applets?
If you have a trusted way of delivering your jars to your client, you do not need to sign it. A "normal" Java program also does not do anything different for a signed jar.
However there is a difference if you use some other way of distributing your application. You already mentioned applets. The user cannot really be sure who is offering the application. By signing it, you can ensure it is comming from the trusted guy (you).
Another big usecase for this is Java Webstart. If you want to distribute your application with that tool (a good idea), you need to sign the Jar files if your application wants to have some extra permissions (like accessing files, network IO, stuff like that). If the user then trusts those certificates, the application is started.
As for the duration: Usually those applications are signed with rather long validity (> 2 years), usually longer than the applications supposed lifetime.
A bit of a noob-who-tries-to-get-a-glimpse-of-something-without-making-homeworks-first question...
Suppose I'd like to include a JVM on a closed source O.S./hardware to be able to provide extended functionalities to customers with addon java applets, and that I'd want to be the only available source to develop and sell addon apps... then is it feaseable to easily implement such a mechanism by simply forcing embedded JVM to only allow execution of apps signed with my digital sign?
In other words I'd just like to know if this is an easy to implement, already proven to work, widely accepted path or just plain BS (for reasons you are free to not tell!) :)
It sounds like what you're wanting is class signing. The startup code for your application can install a SecurityManager to ensure that only classes signed by keys matching some particular criteria can be loaded.
Adding my own answer to get feedback on the following solution, which seems to be the most fitting with my question:
Could Java system policy file be the answer?
As far as I can understand from reading the documentation at http://docs.oracle.com/javase/6/docs/technotes/guides/security/PolicyFiles.html you can basically implement code execution permission policy in 2 ways:
1) implementing and extending permission policy at runtime (what #chrylis refers to).
2) using a default system policy file (java.home\lib\security\java.policy)
The second approach seems easier to implement and kind of more "static" which is a good thing given my use-case because I only need JVM to check that digital sign of app is mine to allow it to run, and will never ever need to extend this policy in any possible way.
So I am not sure yet but given my prerequisites this approach might be what I was looking for in my question... If you have any thoughts just add them, thanks.
I have made a java project and want to deliver it to a client but I don't want to deliver it as a jar file as the client can see the source code easily by unpacking the jar file.
How can I pack my java project so client cannot look at the source code or cannot change the source code?
One more thing, Can I integrate a key functionality so that client can only access that software by first registering it with the key provided by me?
Second, can I integrate another functionality through which the software can run only on a single machine through that key?
Remember, the software should still have the cross-platform functionality and if it is not possible then how can I made it for Debian Linux as I have made it on Windows.
To your first point. Why not only jar up the class files? These are in byte code so the client will not be able to view the source.
As to providing a key. This can be done and there are libraries that allow this, but be careful as , to my knowledge at least, there has yet to be developed a DRM system that hasn't been cracked. and most users do not like software restricting what they can do. The same point applies to your third question.
Obfuscators
There are some simple things you can do to make it a bit difficult for a client to get hold of your source code and to enforce per-host (etcetera) licensing. For example, obfuscators make it harder to reverse engineer bytecode files, and license managers support a range of restrictions based on the "keys" that you generate and supply.
The problem is that none of these protect you against someone who is determined to subvert the restrictions are trying to impose. For example, no obfuscator can prevent someone figuring out where your code calls a license manager, and once they know that they can modify the code to subvert any license checking.
Short of locking down the entire execution platform (e.g. turning of the client's ability to run debuggers, read physical devices and so on), there is nothing you can do about this.
A more viable strategy is to include appropriate protections in the software license that you require the client to sign. And accept that there is a risk that you may need to take clients to court if they willfully violate the license agreement.
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.)
What are the security implications for hosting signed jars on the internet?
As I understand jar signing, once a user choose to auto-accept a certificate, it doesn't matter if the signed jar came from your domain, linked from another domain or hosted on another domain. For example, Sun uses this method to give applets OpenGL support, by providing (hosted) signed jar that link to the driver. So are there any precautions I should make as the developer and certificate-signer of the java-code I make available?
Depending on the context, you are relying on the security manager and associated security policy to do the right thing. Generally unless you are doing your own classloader magic, you shouldn't need to do anything special. If you have control of the security policy, (for example in a java application rather than applet) you can grant permissions to call your jars only to certain other code. If you rely on codebase to distinguish code, a https URL is better. It is also no harm to limit access to the jars on the webserver if you know where/who the accesses should be coming from, but is probably more trouble than it is worth.
However, you should always bear in mind that the caller of your API may not be your code, and may be malicious. So in your threat modelling, you should think about what a malicious user may be able to do if they somehow had access to the functionality given by the API your code exposes. The security manager is supposed to check up the call stack to prevent this kind of thing. But if for example your signed jar has a method LaunchMissiles() ...you might want to ask the user if they are sure anyway. And you might want to authenticate the user too.
Nor should you necessarily rely on the user to click the right button on any security warning, especially if it refers to certificates and URLS etc - most users fall into one of two categories: those who click OK on any warning because they don't understand it, and those who click Cancel on any warning because they don't understand it.