Background information on digital signing.
Now this meant that my applet will not run because my applet is lacking a signed certificate! What is a signed certificate? My understanding is, it is a special code packaged in a jar that identifies one’s legal identity or one’s company’s legal identity. As I will discover, without this certificate my applet will not run (unless I added my website via Java Console to a list of exceptions). So why is java making life so hard? My guess - two reasons: First is to put more accountability on programmers to ensure their code is not malicious or poorly/dangerously written. Second, is to prevent their code from being hijacked and compromised. You see, once the jar has been changed it needs to be “re-signed” and since only you have your certificate – the code will simply not run or will not harm your users machine in your name.
Getting around digital signing – the only way I found was to add my site to a list of exceptions.
There are plenty of instructions on “self-signing” on the internet. I have successfully done this – a few years ago. Unfortunately nowadays it did not matter whether I used a IDE like Netbeans or command prompt style self signing do be an option any more – my applet just would not run! The only way was to add my site to a list of exceptions. But of course if I were making applets for people to use – maybe telling my users to drop all of their security settings might intimidate them or sound too complicated and/or scare them away.
Here is how I went about adding my site to a list of security exceptions: (This was tested on Windows 7)
Click Start| Programs| Java| Configure Java. When the Java Control Panel pop up, I selected the security tab and clicked the Edit Site List. I had to bare in mind: if my file was on a local machine I had to use file:// instead of http://. I then restarted my browser and the result:
Dialog title: Security Warning, Message: Do you want to run this application? An unsigned application from the location below is requesting permission to run. Location: file:// Click Cancel to stop this app or Run to allow it to continue. Options: “Run” “Cancel”.
Selecting run, ran the applet in my browser. Let’s look the other method – getting one’s code digitally certified.
Getting a Digital Certificate
I will be writing about my experience applying for and installing a Digital Certificate. The views here are to give you an idea of the process and are not intended to replace the official instructions provided on the Certificate provider’s website. Please follow their instructions and call them if confused!
So how did I get my digital certificate? Well I had to buy one. These certificates are in price range of about $200 per year – average. Where to get one? I have had success with the Code Signing Certificate product offered at digicert.
It was actually easy to get this working certificate. I selected the Code Signing Certificate, then payment plan. Then I selected Sun Java as my Platform of choice since I write java applets. I then selected to submit my CSR (Code Signing Request) file. I did not have a CSR file, so I had to create one. I used the tool provided on their website.
Here are a few things that I had to either call about or figure out to complete this process:
I applied as an individual as opposed to a company. So in the Organization field, I had to put my legal name, and in the department field I had to write the nature of work I will be doing e.g. Developer.
After clicking the generate button, I had to paste this information in the command prompt. Interestingly, control-V did not work in command prompt. I had to right click in the window and click paste. But this would not work. I got an error saying something like, The command “keytool” is either incorrectly written or not found. So I had to first switch to the directory of the bin folder of the jdk I was using. I used jdk1.8.0_31 so I had to use C:/program Files/java/jdk1.8.0_31/bin/. So I typed in the command prompt “cd c:/program files/java/jdk1.8.0_31/bin/” and then Enter. The directory was changed. I then inserted the code I just generated with the CSR generator and pushed Enter.
But! There was no .jks or .csr files in my bin folder! Now I was not using my computer’s administrator user account, so I don’t know if this had something to do with my error…But I found a solution. I edited the command generated command by adding g:/ to anything that had a .jks or .csr file extension. After the build, my .jks and .csr files were in in my g:/ folder. Now I simply opened my .csr file in notepad, copied and pasted on the contents in the text box digicert provided when I had clicked the select submit my CSR…button.
Now I entered payment info and the order was placed.
I had to provide proof of my identity. After all – my guess – the Digital Certificates provides no security without accountability. So I had to send a scanned copy of my government issued PHOTO ID along with a proof of address (e.g. utility bill). But who to send to? Well – I was very impatient, so immediately after receiving my email I called digicert and told them I wanted to do the Attestation process via skype. Attestation essentially means giving proof of the accuracy of something. The person who answered gave me their email address and confirmed that my choice of documents were appropriate for the Attestation process. He soon after sent me an Attestation form I had to print so that I can sign it while he watched. We made an appointment to meet and within 1 hour I had signed the document while he watched on skype. Approximately 1 to 2 hrs later I received my certificate. Now you might be wondering if skype was my only option. Well it was not, but the other option would require me to have an accountant or a lawyer to do the Attestation process – something I reckoned might be time consuming and maybe even expensive.
The certificate I received via email was a .p7b extension file and had an icon like follows. I blocked out my name with red.
Now that I got my certificate, it was time to install it. The first thing I had to do was update my .jks keystore file. Here I found clear working instructions on how to do so. Again, for this command to work, I had to go to the command prompt and change the directory (prompt “cd c:/program files/java/jdk1.8.0_31/bin/” and then Enter). I had to also write the actual path of the .jks and .p7b files and not just their file names. Push enter and voila! A certificate is born.
Signing an applet.
This process was very easy in Netbeans 8.1. First I opened the projects pane (Widow|Project). I Right clicked on the jar file and then, Properties and finally Web Start. I selected Enable Web Start. For codebase I selected Web Application Deployment.
Under signing I clicked customize.
I selected “Sign by a specified key”. I entered the Keystore Path – this is the .jks file path. I then entered my password, alias (by default mine was set to server) and then entered the Key Password. For mixed code I left as Enabled Software Protections.
I compiled my code – and the output in Netbeans reported in a line saying that the jar was indeed signed. It also warns me that a timestamp was not supplied during the compiling process. To ensure my file is stamped, I would have to use the instructions found on the digicert web page.
Now I had had a signed applet. Let's Run it.
After allowing java to be activated, I got the following dialog.
This message reads: Do you want to run this application. Name: Publisher, Location: this application will run with unrestricted access which may put your computer and personal information at risk. Run this application only if you trust the location and publisher above. Do not show this again for apps from the publisher and location above. Your Options are “Run” and “Cancel”.
I clicked run and the applet ran. This is my first applet in action.
Side note: For my applet that had other jars in it, Netbeans automatically signs them all. If one or more of my jars were not signed, instead of this blue shield with the “i” in the dialog above, I would see a yellow shield telling me that some associated files are not signed. When I tried running my applet via jnlp – I saw the yellow shield. At a later point I will look into how to sign the jnlp file – as it is not a jar file. Here is where I would start.
Setting the manifest file
The last step I had to perform was to "add permissions" to my manifest files. I work in Netbeans as I mentioned before, and what I found was that a manifest.mf file was automatically created in
the projects folder and another in the "build" folder within the projects folder.
I have written JApplets with and without other "dependent" jar/java files. These JApplets have run without fully loading however. To view any exceptions that were possibly being thrown, I had to
turn on the Java Console. Sometimes when the JApplet fails to load a prompt appeared and gave me the options of "Details", "Ignore" or to reload the applet. Clicking "Details" displayed this
In the console what I found was a few missing manifest attribute lines. e.g. "Missing Application-Library-Allowable-Codebase manifest attribute". To fix these problems, I first went to the
manifest.mf file in the myProjectName|build folder. I searched for any of the missing lines:
Application-Name: YOUR APPLICATION NAME
The missing lines I added to the manifest.mf file in the myProjectName folder NOT the build folder within the my project folder. The last line in the manifest.mf file must be
empty - so I pressed enter after my last line.
I compiled my source code and then checked my manifest.mf file in my myProjectName|build folder (NOT THE PROJECT FOLDER). In some of the projects I built however my project|build|
manifest.mf file still did not compile with these manifest attributes. To fix this problem I adjusted the project
file in nbprojects folder. I browsed to myProjectName|nbprojects|project, opened it and scrolled until I found this entry:
# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions)
I inserted the line "manifest.file=manifest.mf" as follows and the attributes I had written in the manifest.mf file in the myProjectName folder now compiled in the manifest.mf file found in the
# Optional override of default Permissions manifest attribute (supported values: sandbox, all-permissions)
The manifest file was built and my JApplet ran without a glitch.
Re-Signing external jar files
Sometimes I use external jar files e.g. Java3d. These external files are the same as the dependent files I mentioned above. However, when compiled and run they caused my applet to get blocked by security! In the console panel, I found Missing Application-Library-Allowable-Codebase manifest attribute (e.g. for j3dcore.jar).
To solve this problem I had to add this attribute to the manifest of the java3d jar files. Here is how I did it:
I now used this jar as my dependent jar. At build, the jar was successfully signed and the applet ran like a charm.
- I copied and pasted the jar to my desktop at location: c:/user/desktop.
- Using the command prompt I extracted the contents of the jar onto the desktop like so:
c:/user/desktop>c:/programs/java/jdk1.8.0_40/bin/jar -xf j3dcore.jar
- I then created a text file and saved as mt.txt using UTF-8 enconding. I then deleted the j3dcore.jar file from my desktop - because now its time to re create the jar file netbeans will like.
- I use the following command to recreate the file:
c:/user/desktop>c:/programs/java/jdk1.8.0_40/bin/jar -cmf mt.txt j3dcore.jar javax (NOTE: 1. mt.txt contained all of the permission, codebase and library-allowable lines that I said were mandatory above. 2. The javax and META-INF were the only folders in this jar so I only listed the javax folder. If there were more folders I would add a space and list them too. The META-INF folder is NOT listed because it creates itself with the permissions listed in mt.txt!)
Side note 1: Now when I initially extracted the jar file, I looked in the META-INF folder. I wanted to see what was written in the manifest.mf file. I found in the folder however, not only a manifest.mf file but also a .sf file and another file. Also the manifest.mf file was 48kb and contained more than 30 lines of code! After re-creating the jar file and then opening it, I found my META-INF folder to only contain the manifest.mf file, and it was just 1 kb with the permissions I had set via the mt.txt file! Well, it just so turns out that the extra lines are added upon build and so are the additional files. These additional lines and additonal files are there to tell the browser if the jar had been modified after it was signed (to block or not block)!)
Side note 2: So I just updated a jar file that had additional jars (as libraries). I uploaded only the main jar. The other jars, which were located in the library folder I did not upload. When I ran the main jar, my other Jars were blocked. So I learnt that whenever you build a jar with dependent jars, every jar must be uploaded to your server!
Check out my working applet here!