Self-signed certificates for a known community

Recently announced changes scheduled for Java 7 update 51 (January 2014) have established that the default security slider will require code signatures and the Permissions Manifest attribute. Code signatures are a common practice recommended in the industry because they help determine that the code your computer will run is the same code that the publisher created.

This post is written to help users that need to use self-signed certificates without involving a public Certificate Authority.

The role of self-signed certificates within a known community

You may still use self-signed certificates within a known community. The difference between self-signed and purchased-from-CA is that your users must import your self-signed certificate to indicate that it is valid, whereas Certificate Authorities are already trusted by default.

This works for known communities where people will trust that my certificate is mine, but does not scale widely where I cannot actually contact or know the systems that will need to trust my certificate. Public Certificate Authorities are widely trusted already because they abide by many different requirements and frequent checks.

An example would be students in a university class sharing their public certificates on a mailing list or web page, employees publishing on the intranet, or a system administrator rolling certificates out to end-users. Managed machines help this because you can automate the rollout, but they are not required -- the major point simply that people will trust and import your certificate.

How to distribute self-signed certificates for a known community

There are several steps required to distribute a self-signed certificate to users so that they will properly trust it. These steps are:

  1. Creating a public/private key pair for signing.
  2. Exporting your public certificate for others
  3. Importing your certificate onto machines that should trust you
  4. Verify work on a different machine

Creating a public/private key pair for signing

Having a public/private key pair will give you the ability both to sign items yourself and issue a Certificate Signing Request (CSR) to a certificate authority.

Create your public/private key pair by following the instructions for creating key pairs.
Every Certificate Authority that I looked at provided similar instructions, but for the sake of cohesiveness I will include the commands that I used here:

  1. Generate the key pair.
    keytool -genkeypair -alias erikcostlow -keyalg EC -keysize 571 -validity 730 -keystore javakeystore_keepsecret.jks
    • Provide a good password for this file.
    • The alias "erikcostlow" is my name and therefore easy to remember. Substitute your name of something like "mykey."
    • The sigalg of EC (Elliptical Curve) and keysize of 571 will give your key a good strong lifetime.
    • All keys are set to expire. Two years or 730 days is a reasonable compromise between not-long-enough and too-long. Most public Certificate Authorities will sign something for one to five years.
    • You will be placing your keys in javakeystore_keepsecret.jks -- this file will contain private keys and therefore should not be shared. If someone else gets these private keys, they can impersonate your signature. Please be cautious about automated cloud backup systems and private key stores.
  2. Answer all the questions. It is important to provide good answers because you will stick with them for the "-validity" days that you specified above.
    What is your first and last name?
      [Unknown]:  First Last
    What is the name of your organizational unit?
      [Unknown]:  Line of Business
    What is the name of your organization?
      [Unknown]:  MyCompany
    What is the name of your City or Locality?
      [Unknown]:  City Name
    What is the name of your State or Province?
      [Unknown]:  CA
    What is the two-letter country code for this unit?
      [Unknown]:  US
    Is CN=First Last, OU=Line of Business, O=MyCompany, L=City, ST=CA, C=US correct?
      [no]:  yes
    Enter key password for <erikcostlow>
            (RETURN if same as keystore password):
  3. Verify your work:
    keytool -list -keystore javakeystore_keepsecret.jks
    You should see your new key pair.

Exporting your public certificate for others

Public Key Infrastructure relies on two simple concepts: the public key may be made public and the private key must be private. By exporting your public certificate, you are able to share it with others who can then import the certificate to trust you.

keytool -exportcert -keystore javakeystore_keepsecret.jks -alias erikcostlow -file erikcostlow.cer

To verify this, you can open the .cer file by double-clicking it on most operating systems. It should show the information that you entered during the creation prompts.

This is the file that you will share with others. They will use this certificate to prove that artifacts signed by this certificate came from you. If you do not manage machines directly, place the certificate file on an area that people within the known community should trust, such as an intranet page.

Import the certificate onto machines that should trust you

In order to trust the certificate, people within your known network must import your certificate into their keystores. The first step is to verify that the certificate is actually yours, which can be done through any band: email, phone, in-person, etc. Known networks can usually do this

Determine the right keystore:

  • For an individual user looking to trust another, the correct file is within that user’s directory.
    e.g. USER_HOME\AppData\LocalLow\Sun\Java\Deployment\security\trusted.certs
    The default password for trusted.certs is an empty string.
  • For system-wide installations, Java’s Certificate Authorities are in JAVA_HOME
    e.g. C:\Program Files\Java\jre8\lib\security\cacerts
    The default password for cacerts is "changeit" as described in the keytool documentation.

File paths for Mac and Linux are included in the link above.

Follow the instructions to import the certificate into the keystore.

keytool -importcert -keystore THEKEYSTOREFROMABOVE -alias erikcostlow -file erikcostlow.cer

In this case, I am still using my name for the alias because it’s easy for me to remember. You may also use an alias of your company name.

Scaling distribution of the import

The easiest way to apply your certificate across many machines is to just push the .certs or cacerts file onto them. When doing this, watch out for any changes that people would have made to this file on their machines.

Trusted.certs: When publishing into user directories, your file will overwrite any keys that the user has added since last update.

CACerts: It is best to re-run the import command with each installation rather than just overwriting the file. If you just keep the same cacerts file between upgrades, you will overwrite any CAs that have been added or removed. By re-importing, you stay up to date with changes.

There is a -storepass argument for specifying the password on the command-line. On secure systems, admins typically hide passwords through redirection operators but that's outside the scope of this post.

Verify work on a different machine

Verification is a way of checking on the client machine to ensure that it properly trusts signed artifacts after you have added your signing certificate. Many people have started using deployment rule sets. You can validate the deployment rule set by:

  1. Create and sign the deployment rule set on the computer that holds the private key.
  2. Copy the deployment rule set on to the different machine where you have imported the signing certificate.
  3. Verify that the Java Control Panel’s security tab shows your deployment rule set.

Verifying an individual JAR file or multiple JAR files

You can test a certificate chain by using the jarsigner command.

jarsigner -verify filename.jar

If the output does not say "jar verified" then run the following command to see why:

jarsigner -verify -verbose -certs filename.jar

Check the output for the term “CertPath not validated.”

Comments:

We are stuck in a situation where we have a third-party, unsigned applet that we need to continue to support for some time after 1.7 Update 51 is released. We've already got a working, signed, Deployment Rule Set that allows users to use this applet without getting errors or warnings under 1.7 update 45. I am under the impression that we be able to continue permitting this unsigned applet to execute, via a Deployment Rule Set, after 1.7 update 51 is released. I'd like to confirm that, however -- is that the case? Assuming it is the case, is there some new syntax we will need to use in the deployment ruleset in order for this to continue working under 1.7 update 51 and higher, or can we stick with the syntax that works currently? Obviously we'd like to get out of the business of running unsigned applets as soon as we can, but we need to have a plan for the interim.

Posted by guest on November 11, 2013 at 03:21 PM PST #

The instructions within this post will give you the ability to sign the Deployment Rule Set JAR file. From your description, it sounds like you've done that and are referencing the unsigned applet with the location attribute: that's fine. There are no syntax changes going on within Deployment Rule Set.

Posted by costlow on November 11, 2013 at 03:43 PM PST #

Thank you, this is very helpful. We will plan to use our Deployment Rule Set to continue supporting access to the unsigned applet even after 1.7 Update 51 is released, until we're able to replace the applet with a properly signed one.

Posted by guest on November 12, 2013 at 11:44 AM PST #

The ruleset might not work in all cases. Especially if java finds a broken partial signature it will not check if it should run unsigned code but block it.

BTW: the user truststore has -storepass "" and the system trust stire has -storepass changeit. If you dont want to use the command line, you can use the java control panel instead, it has a Import button.

Posted by Bernd Eckenfels on November 12, 2013 at 06:15 PM PST #

Good call. I added info about the passwords and -storepass above.
You're on a good track for broken/partial signatures and towards certificate pinning. Maybe a future post.

Posted by costlow on November 12, 2013 at 06:40 PM PST #

So I am a bit confused about these new security updates (and I can not find a better place to ask this question). Based on my understanding, the open-source and/or non-profit lone developer making webstart applets either as personal projects or as part of online resume portfolios have to either pay a couple hundred dollars a year to purchase a commercial CA for a product they will never earn a penny for, or include these rather complex (for the normal end-user) steps to their end-user's deployment instructions. Am I correct here? Because, if so, I am pretty POed.

Posted by guest on December 02, 2013 at 10:57 AM PST #

Non-profit individuals are fine. When writing examples in other posts, I've intentionally used university-like examples to avoid just talking about for-profit companies. A number of CAs have programs for people and IIRC some give free signing certs to valid open-source projects.
If you really don't want to sign code, there's the Exception Site List coming in 7u51 or I've been seeing other posts of people distributing Java programs through app stores (even iOS).

Posted by costlow on December 03, 2013 at 09:52 AM PST #

Post a Comment:
Comments are closed for this entry.
About

Science Duke
This blog contains topics related to Java SE, Java Security and Usability. The target audience is developers, sysadmins and architects that build, deploy and manage Java applications. Contributions come from the Java SE Product Management team.

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
2
3
4
5
6
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today