Restricted-channel multicast in Java

How a desktop stock-ticker app was converted into a secure system, using an applet running on a smart card device

1 2 Page 2
Page 2 of 2

The following for loop iterates once per n-byte (60-byte) block of code, plus once more for the tail-end of the data (which will most likely be of length less than n). The variable len keeps track of the length of the part of data that is being decrypted, so that len equals n (equals 60) in all cases except at the end of the data, when the tail-end is being decrypted, and len is equal to the remainder of the length of the data divided by n (allReceivedBytes.length/60).

The code below also resets the progress meter with each iteration. The number of blocks decrypted so far, divided by the total number of blocks, gives the percent downloaded. After having problems with AWT labels (they sometimes cut off part of the text) I extended Label with an inner class I called SafeLabel. SafeLabel keeps track of the minimum size for a label and changes it whenever the setText(String text) method is called, setting it to the width of text in pixels. It always returns this value to the LayoutManager with the getMinimumSize() method. This prevented, for example, the percent sign (%) getting cut off when the "Downloading:" label reached 100 percent.

int len;
for (int i = 0 ; i <= offsets ; i++) { // step through data n bytes at a time, where n = maxdecodelength
    String dloutput = "Downloading: " + NumberFormat.getPercentInstance().format((double)i/(double)offsets);
    lbDownloading.setText(dloutput);
    len =  (int)Math.min(maxdecodelength, allReceivedBytes.length - maxdecodelength * i);

The next code example attempts to decrypt the segment. If the ring is removed during decryption, the program will loop here until the ring is replaced. Note the check to javaring.isDeviceInserted() (javaring points to a DecoderRing object). This is redundant, as the caught exception produces the same effect within the if statement. It is not clear, however, whether or not this redundancy is unnecessary. The isDeviceInserted method depends on two Open Card methods called cardInserted and cardRemoved. There was some question as to whether these Open Card methods worked reliably with the iButton we were using. Since we weren't sure whether the call to isDeviceInserted was working reliably, we preserved the redundancy. When a successful decryption occurs, the error flag is lowered.

System.arraycopy(allReceivedBytes, i * maxdecodelength, blockToDecode, 0, len);

Copy the n-byte segment into blockToDecode.

while (true) { // try over and over to decode this 60-byte segment
    if (javaring.isDeviceInserted()) {
        try { // try to decode this segment
            blockToDecode = javaring.decipher(blockToDecode); // the decode call
            showerrlabel = false;
            break; // break out of while loop because decode of this segment was successful
        } catch (Exception e) {
            errlabel = ringisoutlabel;
            showerrlabel = true;
        } // try ; catch
    } else {
        showerrlabel = true;
        errlabel = ringisoutlabel;
    } // if(javaring.isDeviceInserted()) ; else
} // while(true)

Once a successful decryption occurs, the plain text is copied back into the original array in the exact same place where its cipher text was removed:

System.arraycopy(blockToDecode, 0, allReceivedBytes, i * maxdecodelength, len);

The program originally waited until the entire incoming multicast message was decrypted before displaying anything; then, while it downloaded a new set of quotes, it displayed the previous set. This would create a problem if the serial port or decryption introduced any kind of delay. Upon starting the program, the user would have to wait to see quotes that were already in memory and decrypted. To fix this problem, I modified the structure of the scroller method such that it actually displays all information as soon as it is available, even if the entire message has not yet been sent through the smart card device. The size of the "message" string grows with each new ring access, as new quotes are appended to those already decoded.

message = new String(allReceivedBytes).substring(0, i *
maxdecodelength + len);

When the ticker has finished decrypting, the download label "disappears":

} // for (int i = 0 ; i <= offsets ; i++)
if (firstdownload) firstdownload = false;
message = new String(allReceivedBytes);
lbDownloading.setText("                 ");

If we were to modify this program so that the user would pay per byte downloaded, rather than paying per string, the code in bold font below would be removed, and ring pullouts after download would not stop the ticker.

} // if(received)
while(waitingforscrolltofinish) {
     if(!javaring.isDeviceInserted())
     {
         errlabel = ringisoutlabel;
         showerrlabel = true;
         while(!javaring.isDeviceInserted());
         showerrlabel = false;
     }
}

The code below most likely would be moved inside the for loop, so that the ring would be billed incrementally for each 60-byte block. It's probable that this code will need to be modified when a purse is actually implemented. At present, this loop continually tests the stub purse until it is found to contain enough money to pay for the next download. Again, showErrLabel is used, with a different error message:

while(true) {
     try {
         decrementMoney(rate);
         showerrlabel = false;
         break;
     } catch (OutOfMoneyException e) {
         errlabel = outofmoneylabel;
         showerrlabel = true;
            }
         } // while(true)
     } // while(true)
} // run()

Java Card is real and portability works

Java Card is a standard that allows developers to write programs for smart cards that are portable among different manufacturers' cards. In addition to the advantages brought by portability, because Java Card is actually a language and is a proper subset of Java, Java-trained developers can learn to write Java Card applets relatively quickly. Traditionally, smart card programmers were in-house staff hired by the smart card manufacturers themselves, which meant that smart card programming was essentially equivalent to embedded systems programming. Java Card moves smart card programming away from the card manufacturers to the users. Perhaps users will be more inventive in terms of creating new and more specialized applications for smart cards, which may in turn will bring about an increase in the popularity of the cards as a whole. Additionally, the new portability of Java Card applications may encourage competition among smart card manufacturers, who will no longer be able to claim their card is the only card that provides a given functionality. The Java Card applet associated with our SecureStockViewer was originally tested and run on a Dallas Semiconductor iButton (a Java Ring) and was then ported with minimal-to-no tinkering to a GemXpresso card and a Schlumberger card. You can get your development kits at the Web sites listed in the Resources section.

Conclusion

From a business perspective, it has become obvious to us that multicast is an unexplored and potentially very exciting direction in network applications and applets. Restricted-channel multicast won't be the only multicast out there. With the growth of e-commerce, the need for stream-oriented paid-for content will arise, and developers who are ready to create such applications and applets will be in high demand. I also get the feeling that as e-commerce develops, smart cards and other token devices will pop up over and over again as the most convenient way of regulating payment. Encryption, of course, will guide e-commerce, and a strong background in it will be an absolute requirement for any developer in this area. Still, multicast and token devices will be some of the more important parts of e-commerce enabled by new advances in encryption. As a first-time programmer of a multicast application, I found the JRMS package and the Dallas Semiconductor iButton easy to understand and work with, and I hope I can continue to work on this project or others like it.

Jason Scherer is an intern and first-time Java programmer at Sun Microsystems. He will receive his BA in Computer Science from Columbia University in December of 1998. He has been programming in C for two years and has worked for Lockheed Martin in San Jose and for the Columbia University Applied Physics Department. He is interested in cryptography, user interfaces and graphics, language and compiler design, and mathematics. Hobbies include composing electronic music. He lives in New York with his fiancee Rachel. You can check out his Web site at http://www.columbia.edu/~jps19.

Learn more about this topic

Related:
1 2 Page 2
Page 2 of 2