Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Using JCE in a J2ME environment

Secure pervasive computing technologies with platform-independent solutions

Lin Ma (mallin@cn.ibm.com), Software Engineer, IBM, Software Group
Lin Ma is a Software Engineer at the IBM China Software Development Lab. His work focuses on pervasive computing technologies and services. He can be reached at mallin@cn.ibm.com.
Yu Chen Zhou (zhouyuc@cn.ibm.com), Staff Software Engineer, IBM, Software Group
Yu Chen Zhou is a Staff Software Engineer at the IBM China Software Development Lab. His work focuses on pervasive and portal solutions. He can be reached at zhouyuc@cn.ibm.com.
Lei Ma (malei@cn.ibm.com), Software Engineer, IBM, Software Group
Lei Ma is a Software Engineer at the IBM China Software Development Lab focusing on pervasive computing technologies. He can be reached at malei@cn.ibm.com.
Jian Lin (jianlin@cn.ibm.com), Manager, IBM, Software Group
Jian Lin is the Manager of Pervasive Computing Device Software Development and Services, IBM China Software Development Lab. He can be reached at jianlin@cn.ibm.com.

Summary:  Learn a platform-independent approach for transitioning Java Cryptography Extension (JCE) to Java 2 Platform, Micro Edition (J2ME) environments.

Date:  23 Nov 2004
Level:  Intermediate

Activity:  7200 views
Comments:  

Introduction

Today, with the advent of pervasive computing technology, you can deploy many kinds of applications, including multimedia services and online interactive games, into a Java 2 Platform, Micro Edition (J2ME) environment. However, security becomes an important issue in order for applications to perform AAA (Authenticate, Authorize, and Audit) operations. Java Cryptography Extension (JCE) is the widely adopted standard security library used in Java 2 Platform, Standard Edition (J2SE) environments. This article helps you transition JCE to J2ME environments with a platform-independent, troubleshooting approach.


Setbacks for implementing JCE in J2ME

In this article, we analyze the common issues associated with using JCE, the standard security library for J2SE, in a J2ME environment. We illustrate how to solve these problems step by step, including sample code, and show how to implement the AES (Advanced Encryption Standard) algorithm with JCE in a J2ME environment. For our working environment, we will use IBM® WebSphere® Studio Device Developer (Device Developer), Foundation Profile, and IBM JCE. However, because the tools and libraries we use conform to an open standard, you can apply the approach to all other kinds of development environments that adhere to J2ME and JCE standards.

To start, we'll review the two steps required in the standard JCE installation for J2SE. The first step is adding a JCE provider, such as the IBM JCE provider, into the java.security file. Listing 1 shows how.


Listing 1. Registering a JCE provider
security.provider.1=com.sun.crypto.provider.SunJCE
security.provider.2=com.ibm.crypto.provider.IBMJCE

The second step is adding JCE-related library files into the CLASSPATH. In IBM JCE, the library files are:

  • ibmjcefw.jar
  • ibmjceprovider.jar
  • ibmpkcs.jar
  • ibmpkcs11.jar
  • local_policy.jar
  • US_export_policy.jar

If you follow these steps for a J2ME environment, however, two kinds of exceptions will likely be thrown: untrusted CA exception or resource not found exception. Listing 2 shows the first kind of exception.


Listing 2. Untrusted CA exception
java.lang.ExceptionInInitializerError:
java.lang.SecurityException: Cannot set up certs for trusted CAs

Listing 3 shows the second kind of exception.


Listing 3. Resource not found exception
NoClassDefFoundError: javax/crypto/KeyGenerator at ...

Before we solve the exceptions, let's review some background. First, for different versions and types of development tools (JDK, JCE, and even operating systems) an exception belongs to either one of these types: one that deals with CA certificates, or one that deals with a failure to look for prerequisite classes even if they already exist in the CLASSPATH. Exceptions of the same type are similar in nature but reveal different error messages.

Second, according to our tests on many different platforms, only one kind of exception is likely to occur, and, although rare, on some platforms no exception occurs.

Finally, this article does not target a solution for a specific platform, but shows a general way to solve these kinds of exceptions.


Platform-independent solutions

Now, we'll examine the cause of these exceptions and some platform-independent solutions (IDE, JDK, JCE, and operating systems). During prior tests, we found that the two kinds of exceptions result from one of three causes:

  • An environment variable
  • The integrated development environment's (IDE) internal file system implementation
  • The JCE library's registration mechanism

The first cause deals with the environment variable java.home in the java.policy file. JCE libraries must be authorized to have all permissions in the Java Virtual Machine (JVM), as Listing 4 shows; otherwise, the application cannot work.


Listing 4. A sample of the java.policy file
// by default, all system extensions get AllPermission
grant codeBase "file:${java.home}/lib/ext/*" {
                 permission java.security.AllPermission;
};

Notice that there is a system environment variable called java.home. On different platforms, the value of this variable changes. For example, in our environment the value is C:\WSDD571\wsdd5.0\ive-2.2. On another machine the value might be C:\Program Files\IBM\DeviceDeveloper\wsdd5.0\ive-2.2. To enable JCE libraries to have all permissions, we have to place the libraries into the %java.home%/lib/ext/ directory (we use %java.home% to identify the value of the environment variable java.home), and in our environment the value is C:\WSDD571\wsdd5.0\ive-2.2\lib\ext. However, the default installation of some IDEs, including our working IDE, does not create the ext subdirectory automatically during installation; therefore, we must develop the directory manually and put JCE libraries into it.

The second cause relates to the IDE's internal file system implementation. Some IDEs use URLs similar to the representation for local files, causing the IDE to possibly misinterpret special characters (a common example is the space character). You should exclude characters in the IDE's home directory name that have special meaning in a URL presentation.

The third cause deals with the JCE library's registration mechanism. There are two ways to load JCE libraries: static registration (presented in the first section) and dynamic loading. To load dynamically, a program can call either the addProvider() or insertProviderAt() methods in the Security class. Listing 5 shows the dynamic registration of the IBM JCE provider.


Listing 5. A sample dynamic registration of the JCE provider
Provider IBMJce = new com.ibm.crypto.provider.IBMJCE();
Security.addProvider(IBMJce);

For some platforms, only one of these loading mechanisms can work. If one registration approach is not working, simply try the other mechanism; their functions are the same. However, we have found that in some versions of Device Developer, only the dynamic approach works.


A detailed configuration process in Device Developer

Now, we'll detail the configuration process for our working environment. While the cause-of-exception analyses are relatively complex and tricky, the configuration process is fairly simple:

  1. For static registration only, you must first register the IBM JCE provider to the java.security file by appending the following line to the java.provider entry in this file.


    Listing 6. IBM JCE provider entry in the java.security file

    security.provider.2=com.ibm.crypto.provider.IBMJCE
    

    Listing 7 shows the whole java.provider entry in the java.security file for our environment.


    Listing 7. The whole JCE provider entry in the java.security file
    # set the provider for security
    security.provider.1=com.ibm.oti.security.provider.OTI
    security.provider.2=com.ibm.crypto.provider.IBMJCE
    

    Also note that an IDE might contain many files named java.security. In our Device Developer environment, the proper file is located in the C:\WSDD571\wsdd5.0\ive-2.2\lib\security directory. We have verified that adding provider information to other files with the same name has no effect on applications that use JCE in a J2ME environment.

  2. In the Java Development Kit (JDK) directory of Device Developer, which for our working environment is C:\WSDD571\wsdd5.0\ive-2.2\lib, we create a directory named ext if it does not exist. Then we put IBM JCE library files, including ibmjcefw.jar, ibmjceprovider.jar, ibmpkcs.jar, ibmpkcs11.jar, local_policy.jar, and US_export_policy.jar into the JDK library's extension directory. In our working environment, the directory is C:\WSDD571\wsdd5.0\ive-2.2\lib\ext.

  3. To register the new variable JCE in Device Developer:
    1. Invoke the project's properties window, as shown in Figure 1.
      Figure 1. The project property window
      The project property window
    2. Select Java Build Path from the left frame, shown in Figure 2.
      Figure 2. The Java build path window
      The Java build path window
    3. Select Add Variable, as shown in Figure 3.
      Figure 3. The project property window
      The project property window
    4. Select Edit.
      Figure 4. The edit window
      The edit window
    5. Select New and enter the correct values. In our working environment, we use JCE as the variable name and C:/WSDD571/wsdd5.0/ive-2.2/lib/ext as the path value. You can generate the path value automatically through the Folder button.
      Figure 5. The new variable entry window
      The new variable entry window
    6. Select OK twice and the window shown in Figure 6 appears.
      Figure 6. The window after clicking OK two times
      The window after clicking OK
    7. Select JCE and click Extend (Figure 7).
      Figure 7. Select JCE and extend
      Select JCE and extend
    8. Select all entries.
      Figure 8. Select all entries
      Select all entries
    9. Select OK. The IDE should look like Figure 9.
      Figure 9. Final IDE
      Final IDE
    10. Finally, select OK.
  4. Follow this process to register the JCE variable on all the machines your team uses. Your team will share the same variable name, JCE, but the variable's values for each machine can be different.

  5. Note that the Device Developer installation home directory should not contain special characters such as the space character. In our working environment, the Device Developer installation home directory is C:\WSDD571. This step is not required because some platform IDEs work with directory names containing special characters. But we do recommend taking precautions by following this step.

Sample source code

This section provides two sample programs. The first one, shown in Listing 8, deals with the dynamic registration approach; the second, in Listing 9, deals with the static registration approach. If JCE is configured correctly, both programs can run in J2ME and J2SE environments without any modification, proving that this solution supports developers creating real "write once, run everywhere" Java programs.


Listing 8. Dynamic registration approach sample source code
package com.ibm.osg.sample.simple;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.ibm.crypto.provider.IBMJCE;
   /**
   * This program generates an AES key, retrieves its raw bytes, and
   * then reinstantiates an AES key from the key bytes.
   * The reinstantiated key is used to initialize an AES cipher for
   * encryption and decryption.
   */

   public class AES {

     /**
     * Turns array of bytes into string
     *
     * @param buf                Array of bytes to convert to hex string
     * @return           Generated hex string
     */
     public static String asHex (byte buf[]) {
      StringBuffer strbuf = new StringBuffer(buf.length * 2);
      int i;

      for (i = 0; i < buf.length; i++) {
       if (((int) buf[i] & 0xff) < 0x10)
                     strbuf.append("0");

       strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
      }

      return strbuf.toString();
     }

     public static void main(String[] args) throws Exception {

                                 System.out.println ("Zzz: " + 
System.getProperty("java.home"));

                                 // Instantiate the cipher
                                 IBMJCE jce = new IBMJCE();
                                 Security.addProvider(jce);
        String message="This is just an example";

       // Get the KeyGenerator

       KeyGenerator kgen = KeyGenerator.getInstance("AES", "IBMJCE");
       kgen.init(128); // 192 and 256 bits may not be available

       // Generate the secret key specs.
       SecretKey skey = kgen.generateKey();
       byte[] raw = skey.getEncoded();

       SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

                    Cipher cipher = Cipher.getInstance("AES", "IBMJCE");
       cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

       byte[] encrypted =
         cipher.doFinal ("This is just an example".getBytes());
       System.out.println("encrypted string: " + asHex(encrypted));

       cipher.init(Cipher.DECRYPT_MODE, skeySpec);
       byte[] original =
         cipher.doFinal(encrypted);
       String originalString = new String(original);
       System.out.println("Original string: " +
         originalString + " " + asHex(original));
     }
   }


Listing 9. Static registration approach sample
package com.ibm.osg.sample.simple;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


import com.ibm.crypto.provider.IBMJCE;
   /**
   * This program generates an AES key, retrieves its raw bytes, and
   * then reinstantiates an AES key from the key bytes.
   * The reinstantiated key is used to initialize an AES cipher for
   * encryption and decryption.
   */

   public class AES {

     /**
     * Turns array of bytes into string
     *
     * @param buf                Array of bytes to convert to hex string
     * @return           Generated hex string
     */
     public static String asHex (byte buf[]) {
      StringBuffer strbuf = new StringBuffer(buf.length * 2);
      int i;

      for (i = 0; i < buf.length; i++) {
       if (((int) buf[i] & 0xff) < 0x10)
                     strbuf.append("0");

       strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
      }

      return strbuf.toString();
     }

     public static void main(String[] args) throws Exception {

                 System.out.println ("Zzz: " + 
System.getProperty("java.home"));

        String message="This is just an example";

       // Get the KeyGenerator

       KeyGenerator kgen = KeyGenerator.getInstance("AES", "IBMJCE");
       kgen.init(128); // 192 and 256 bits may not be available

       // Generate the secret key specs.
       SecretKey skey = kgen.generateKey();
       byte[] raw = skey.getEncoded();

       SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");

                    Cipher cipher = Cipher.getInstance("AES", "IBMJCE");
       cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

       byte[] encrypted =
         cipher.doFinal ("This is just an example".getBytes());
       System.out.println("encrypted string: " + asHex(encrypted));

       cipher.init(Cipher.DECRYPT_MODE, skeySpec);
       byte[] original =
         cipher.doFinal(encrypted);
       String originalString = new String(original);
       System.out.println("Original string: " +
         originalString + " " + asHex(original));
     }
   }


Conclusion

Though this solution for using JCE in J2ME development works in the sample environment, you should consider it carefully before using it. First, using JCE to provide cipher functions is one way to offer security solutions, which can save you time writing customized cipher libraries. But note that JCE is a relatively large library and has a big footprint relative to the J2ME environment. For mission-critical applications, light-weight customized cipher libraries are more suitable. Additionally, JCE is not currently part of the J2ME specification. Therefore, you must consider compatibility and legal issues if you are targeting a commercial product. Thorough testing is the only way to verify compatibility.


Resources

  • Learn about and even download Cloudscape, a small-footprint database for embedding Java applications (it's user-friendly and requires no administration for end users).

  • Read Java Security, Second Edition, (Scott Oaks, 2001, O'Reilly) to learn about the Java features that provide security.

  • Also read Cryptography and Network Security Principles and Practices, Third Edition, (William Stallings, 2003, Prentice Hall) for comprehensive information on computer organization.

  • For more about JCE, review the Java Cryptography Extension (JCE) Documents.

  • Visit the IBM WebSphere Device Developer Web site and learn how Device Developer can help you.

  • Review the specifications at J2ME technology resources to learn more about J2ME.

  • Review the specifications at J2ME Foundation Profile Specification for information on supporting resource-constrained devices without a standards-based GUI system.

  • Browse for books on these and other technical topics.

About the authors

Lin Ma is a Software Engineer at the IBM China Software Development Lab. His work focuses on pervasive computing technologies and services. He can be reached at mallin@cn.ibm.com.

Yu Chen Zhou is a Staff Software Engineer at the IBM China Software Development Lab. His work focuses on pervasive and portal solutions. He can be reached at zhouyuc@cn.ibm.com.

Lei Ma is a Software Engineer at the IBM China Software Development Lab focusing on pervasive computing technologies. He can be reached at malei@cn.ibm.com.

Jian Lin is the Manager of Pervasive Computing Device Software Development and Services, IBM China Software Development Lab. He can be reached at jianlin@cn.ibm.com.

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=32031
ArticleTitle=Using JCE in a J2ME environment
publish-date=11232004
author1-email=mallin@cn.ibm.com
author1-email-cc=
author2-email=zhouyuc@cn.ibm.com
author2-email-cc=
author3-email=malei@cn.ibm.com
author3-email-cc=
author4-email=jianlin@cn.ibm.com
author4-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

For articles in technology zones (such as Java technology, Linux, Open source, XML), Popular tags shows the top tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), Popular tags shows the top tags for just that product zone.

For articles in technology zones (such as Java technology, Linux, Open source, XML), My tags shows your tags for all technology zones. For articles in product zones (such as Info Mgmt, Rational, WebSphere), My tags shows your tags for just that product zone.

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Special offers