About MIDlet Suite Signing
As of release 0.7.0, EclipseME supports cryptographic signing of MIDlet suites. This page provides background material on the signing process, provides an overview of how you go about signing a MIDlet suite manually, and then describes how EclipseME handles this.
Under the MIDP 1.0 specification, all MIDlets operated using a "sandbox" security model. Essentially, a MIDlet could only access API's that were specifically included as part of the MIDP 1.0 specification, or to libraries that were bundled as part of the same MIDlet suite.
MIDP 2.0 (JSR-118) introduced the concept of "trusted" and "untrusted" MIDlet suites. An "untrusted" suite operates under the same restrictions as in MIDP 1.0 - the only API's that can be accessed are those that are part of the MIDP specification. "Trusted" suites can be granted access to a wider selection of API's on the device. In addition, as part of the MIDP 2.0 specification, certain "standard" API's were provided that required authorization to use. For example, an untrusted MIDlet suite must be able to access the javax.microedition.io.HttpConnection API, but the system is required to make the user confirm that it is OK for the MIDlet suite to use this API.
Trusted MIDlet suites can, on the other hand, be granted access to API's without explicit user authorization, and may have access to API's that an untrusted MIDlet is not allowed to access. Details of all of this are spelled out in JSR-118, and so will not be repeated here.
The basic steps in signing a MIDlet suite are:
A MIDlet requests permissions by declaring them in the application descriptor and JAR manifest, using either MIDlet-Permissions or MIDlet-Permissions-Opt tag. Multiple permissions can be specified with either tag, and are separated by commas. During the installation process, the device is required to look at the requested permissions. If a permission is declared in MIDlet-Permissions, then the device must either be prepared to install the MIDlet in a protection domain that grants access to these features, or the device must abort the installation. However, if the permission is declared in MIDlet-Permissions-Opt, and the MIDlet suite fails to gain access to an appropriate protection domain, the installation can continue but the suite will not have access to the requested permission. So, if your MIDlet suite depends on having a permission, and cannot operate without it, this permission should be requested in MIDlet-Permissions.
If your application can live without a specific permission, but would make use of the feature if access is granted, request the permission using MIDlet-Permissions-Opt. If your MIDlet is not granted permission to the feature, you should get a SecurityException when you try to access it. Note that for HTTP in particular, certain device providers violate the specification just slightly and throw an IOException, instead of a SecurityException, in an odd attempt to be compatible with MIDP 1.0. Check your tookit provider's documentation on this.
The following is an example of requested permissions in a JAD file. The MIDlet suite is indicating it must have access to HTTP and HTTPS and would like to have access to the PushRegistry, VideoControl.getSnapshot, and SMS. If the latter three are denied, the suite can adjust and still provide value to the user.
MIDlet-Permissions: javax.microedition.io.Connector.http, javax.microedition.io.Connector.https MIDlet-Permissions-Opt: javax.microedition.io.PushRegistry, javax.microedition.media.control.VideoControl.getSnapshot, javax.wireless.messaging.sms.receive, javax.wireless.messaging.sms.send
In this example, HTTP and HTTPS are not requested as optional. Because the application has indicated it cannot function without these resources, if the device is unable to grant these permissions on installation, the installation will abort. Whether or not the device will be able to grant permission is dependent on its own security policies, and whether or not the MIDlet is trusted. In order to be trusted, the MIDlet must be signed.
MIDlet security is based around public key cryptography. The basic steps are:
Since only your private key can generate information that your public key can decrypt, so as long as you keep your private key a secret, the world can be sure that anything that can be verified by your public key was prepared by you.
Of course, this still begs the question of how someone knows that a particular public key really came from you. What is to prevent me from claiming to be Bill Gates, and digitally signing documents accordingly? Instead of just including your public key in the MIDlet suite, you include a certificate that, in turn, includes the public key. The certificate is issued by a trusted third party such as Verisign, and essentially promises that this public key really did come from you.
How does the device know to trust the Verisign certificate? Devices are programmed with a set of "root certificate authorities" that they will always trust. Certificates are themselves signed, using information that is pre-programmed into the phones. Thus, the device can verify that your certificate was actually issued by Verisign by using its pre-programmed information. Alternately, your certificate may be signed by an "intermediate" key, which is itself, in turn, signed by a trusted key. This is called a "certificate chain." Chains can actually be any number of keys in length, although it's rare that they contain more than two or three links.
As a result, the process for getting your keys set up typically works like this:
As part of its JDK, Sun provides a tool that will help with the management of keys. The tool is, appropriately enough, named keytool.
To generate a new public/private key pair, you execute the command:
keytool -genkey -keyalg RSA -keystore <keystore file name>
This instructs the tool to build a new RSA public/private key pair, and place it in the specified "keystore" file. As part of this process, you will be asked a variety of information about yourself. In addition, you will be asked for the following items:
| Key Alias | A keystore can hold multiple key/certificate pairs. The "alias" identifies the particular one with the keystore file |
| Keystore password | Your keystore obviously contains information that not just anybody should have access to. As a result, the keystore file is stored in an encrypted format. This is the password that grants access to the keystore file |
| Key password | With the keystore password, you gain access to the "public" half of the keystore - the public keys and certificates. In order to access the private key, an additional, key-specific password is required. This protects the private key even more than the rest of the keystore information. |
It is possible to specify all these quantities from the command line of keytool if you want. Run
keytool -help
or consult the documentation on Sun's site for more information about this.
If all you want to do is to "play" with signing, you can skip the rest of this section and jump down to the discussion on signing. When you generate your key, keytool automatically adds a "self-signed certificate" to the keystore. This certificate is of the correct format to allow a MIDlet suite to be signed with it. Note that this will NOT result in your MIDlet suite becoming trusted in production, since your mobile device will not be able to verify this "personal" certificate with any of its trusted certificate authorities. To do that, you have to go through the proper certificate request process described below. The "self-signed" certificate, however, is sufficient if all you want to do is experiment with EclipseME's signing support - you can wait and get a "real" certificate later.
To generate a certificate request using keytool, execute the following command:
keytool -certreq -keystore <keystore file name> [-storepass <storepass>]
[-alias <alias>] [-file <request file>] [-keypass <keypass>]
Items in brackets are optional - keytool will automatically prompt you for any items you don't specify on the command line.
Once you have generated your certificate request, send it off to your certificate authority. When they return the certificate to you, you then import it into your keystore using the command:
keytool -import -keystore <keystore file name> [-storepass <storepass>]
[-alias <alias>] [-file <certificate file>] [-keypass <keypass>]
This replaces the "self signed" certificate generated by keytool with the propertly signed certificate from the certificate authority. At this point you are ready to use the information in the keystore file to sign your MIDlet suite.
If you were not using EclipseME, you would probably use JADTool to sign your suite. JADTool is a signing tool provided by Sun and many other vendors as part of its Wireless Toolkits.
Signing using JADTool is a two-step process: first you add the JAR signature to the JAD file using the command
java -jar JADTool.jar -addjarsig -keypass <password> -alias <key alias>
-storepass <password> -keystore <keystore> -inputjad <filename>
[-jarfile <filename>] [-outputjad <filename>]
This computes a checksum on the JAR file, signs it with your private key, and encodes the result into the JAD file. The second step is to put your public key certificate into the JAD file, using the command
java -jar JADTool.jar -addcert -keypass <password> -alias <key alias>
-storepass <password> -keystore <keystore> -inputjad <filename>
[-jarfile <filename>] [-outputjad <filename>]
This extracts the certificate from the keystore, encodes it, and places it in the JAD file. At this point, your MIDlet suite is fully signed. If you inspected the JAD file after signing, you would see that it contains two lines that look something like this:
MIDlet-Jar-RSA-SHA1: VPHnTUqz5+R6G29HTtEfIC4DOpXzpCa9U3zBqe0kGhOitgh1wwdcK4jcQnfj
STD9kPRfheWiIwC8xeCs08wdlE9xY/v8veYic0cj6GtSm03EgL5Mc+KRSNfitVIL7xa5LWY7yTCi7IkiI
DqC+dP8KQjoCReGsU0YoPM9iq6b6dM=
MIDlet-Certificate-1-1: MIICUjCCAbsCBEGjQ2AwDQYJKoZIhvcNAQEEBQAwcDELMAkGA1UEBhMCV
VMxCzAJBgNVBAgTAkZMMRMwEQYDVQQHEwpGb3J0IE15ZXJzMRIwEAYDVQQKEwlFY2xpcHNlTUUxFDASBg
NVBAsTC0RldmVsb3BtZW50MRUwEwYDVQQDEwxLZXZpbiBIdW50ZXIwHhcNMDQxMTIzMTQwNDE2WhcNMDU
wMjIxMTQwNDE2WjBwMQswCQYDVQQGEwJVUzELMAkGA1UECBMCRkwxEzARBgNVBAcTCkZvcnQgTXllcnMx
EjAQBgNVBAoTCUVjbGlwc2VNRTEUMBIGA1UECxMLRGV2ZWxvcG1lbnQxFTATBgNVBAMTDEtldmluIEh1b
nRlcjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA1uL1PGDcD/u1Ki12gZntby2lJmizbzDpbLSV30
fs5BRO21dC2XY99X7igoc0+O2Ic5qSzY7x2r9rQf0c+d8hA9T3w4tjQBNizEdkvxFNcFFNrAo5MdzWvcU
PiCODqthy1O9LrCAomp/+2d5N+TGOgtUXocgDPouaT/rfKQujI5sCAwEAATANBgkqhkiG9w0BAQQFAAOB
gQBIQ4ECwjj3spYOhxsih55F7e0Prx+evi6VYBaWoZTGKjevnW3IkKTijytdoMpBX3r7oBjAIibFlSEqU
JfJRMszq/L9JOnIcEKRIvkW8yN/Ls8pWB5VEir2EUh3kiIgk2zo7uhbjs58b5bOjWhTZMhQjPI22I23Tq
a/HKXNBsTL3A==
The first line is the encrypted JAR file checksum, while the second is the certificate containing your public key. If your certificate authority gave you back a certificate with an intermediate certificate (a multi-part certificate chain), there might be a MIDlet-Certificate-1-2 item as well.
Having signed your MIDlet suite, your mobile device can verify the MIDlet suite by:
If the two items match in the last step, the mobile device can be confident that
Finally, many devices will then check to see that the set of permissions requested in the JAR file's MANIFEST.MF file match the permissions requested in the JAD file.
As you can see from the above, using JADTool with EclipseME would require you to deploy your MIDlet in a two-step process. First, you would need to build the MIDlet suite using EclipseME, then you would have to use JADTool manually in order to add the signature information into the JAD file. You would have to repeat this process every time you made a change to your MIDlet suite. Obviously, it could get a bit tedious to do this every time you changed a line of code and then wanted to fire up the emulator.
Beginning with version 0.7.0, EclipseME can now perform the functions that would have required JADTool in the past. To do this, you need to do the following:
Once this is done, EclipseME will then handle both of the steps for which JADTool would have been used. As a result, your MIDlet suite will be automatically signed as part of every deployment operation.
When setting up signing, it is best to use the Verify Settings button. This will ensure that the path to the keystore, the key alias, and the keystore and key passwords are all correct. In addition, since keystores can manage multiple different kinds of keys, this operation verifies that the key identified by the alias is of the proper type (RSA) to be used for MIDlet suite signing.
Note that EclipseME is not capable, at present, of helping you to actually obtain the key/certificate pair required to sign your MIDlet suite. For the moment, you will still need to go through the steps described above to generate a key and arrange for a certificate to be issued for it. Once you have the proper information in your keystore, however, EclipseME can take it from there.
One thing that we need to point out is that EclipseME needs access to the keystore password and key password in order to sign the MIDlet suite. We have provided three methods that you can use for managing these passwords:
Different emulators behave differently with regard to signed MIDlets. Many emulators allow you to specify a particular security domain under which a MIDlet is to be emulated. For emulators that support this, beginning with EclipseME 0.7.0, there is an additional item on the Launch Configuration Settings that allows you to specify the security domain.
Note: If you are signing your MIDlet with a certificate obtained from a certificate authority (or one you have created yourself for testing purposes), it may be necessary for you to import that certificate into your emulator for your signed MIDlet to work properly. This is particularly the case for Over-The-Air (OTA) emulation. Alternately, it may be necessary for you to sign your MIDlet with an emulator-supported certificate. Consult your emulator's documentation for more information.
The following are some (hopefully) useful references to the signing process and the properties of signed MIDlets: