Download: [source code] Computer applications use ciphers to protect sensitive information from theft. Encrypted data can be safely transmitted over an insecure network like the Internet. This article shows how encryption protects data from eavesdroppers, then presents a complete example that shows how to use the Bouncy Castle Cryptography APIs to encrypt messages sent between two MIDP devices. For background on ciphers and encryption, read the first part of this series, Design Concepts and Cryptography. Contents
Network Data Is Easily Stolen Data follows a complicated path from a MIDP device to an Internet server, a path that is full of opportunities for eavesdropping. The device itself broadcasts data on radio waves; the intended destination is a cell tower, but an eavesdropper with the proper equipment can pull the data out of the air. Once the data reaches the carrier's land wired network, it can be intercepted by equipment in that network. At some point the data passes from the carrier's land network into the Internet, where it travels through a variety of network equipment. At any point, the data is more or less available to anyone with the correct equipment and knowledge. Interception tools are readily available. Ethereal, a protocol analyzer, can record all of the data transmitted on an Ethernet network. An eavesdropper with a laptop computer can use Ethereal to record data passing through various points in the Internet. The following screen shot shows part of the data exchanged between a server and a browser. The highlighted portion shows how the data (an HTML page, in this case) is readily available.
Most of the time, using an HTTPS connection in place of an HTTP connection provides adequate data security. The endpoints of the HTTPS connection agree on a session key that is used to encrypt the remainder of the conversation. After the initial handshake, all data is encrypted. Using Ethereal or a similar tool on an HTTPS connection isn't very useful:
The cryptographic services that HTTPS connections or TLS sockets provide are adequate for most applications. In some cases, however, you may need to provide your own encryption:
For more information on HTTPS and TLS, read Understanding SSL and TLS. Bouncy Castle to the RescueFortunately you don't have to implement cryptographic algorithms yourself. You can use the Bouncy Castle Cryptography APIs. The hard-working folks at Bouncy Castle provide implementations of many different cryptographic algorithms. There's even a lightweight package that's suitable for MIDP applications. Using the Bouncy Castle APIs in a MIDP project is a little tricky. You'll need to use an obfuscator, both to reduce the size or your MIDlet suite and to rename some of the Bouncy Castle classes. For the full details, see Authentication in MIDP. Make Sure You Know What You're DoingCryptography is tricky. The Bouncy Castle APIs give you a lot of power, but it's power that can be used well or poorly. It's surprising how easy it is to implement application security badly. If you think you can't wait to add cryptography to your own application, just take a deep breath and step back for a moment. If TLS will meet your needs, use it instead. TLS is a sophisticated and battle-tested protocol with a lot of power and flexibility. One of its biggest advantages is that developers can use it effectively without needing exhaustive cryptographic knowledge. If TLS really won't do the job for you, then be sure you have a deep enough understanding of cryptography and security to build your own solution. Read lots of books and ask lots of questions. Have others review the system design and source code for security flaws. The Whisper ExampleThe example code for this article is the Whisper example, a simple application that uses the Wireless Messaging API (WMA, JSR 120) to send and receive encrypted SMS binary messages. Distributing keys is a little tricky, but I'll talk about that later. Right now I'll show you how to take the application for a test drive. The following example was built from the available download and the Bouncy Casle Cryptographic package. Two separate MIDlet suites were built using the Wireless Toolkit, one suite for Fleur and another for Viktor. Fleur's MIDlet suite contains Viktor's name, address and key file. The name and address are contained in the JAD file as the property: Whisper-Peer-1: Viktor|5550000and the JAR file contains Viktor's key in a resource named: Peer-5550000.keyViktor's MIDlet suite is constructed in a similar fashion to contain Fleur's name, address and key file. You need to run Viktor's MIDlet suite first, because his emulator needs to have the number 5550000. (This is the first number that will be assigned to the emulator when it is run, assuming you are using the toolkit's default settings.) Run Viktor's application by double-clicking on the descriptor file. After it's running, start up Fleur's, which should come up with the number 5550001. The emulator asks you whether to allow the Whisper example to make network connections. Say yes to everything to continue. The two emulators look much the same:
To send a message in either emulator, choose New. A pop-up screen lets you select a recipient (this simple demonstration provides only one). Enter your message and choose the Send command. Behind the scenes, the Whisper example encrypts your information and sends it as a binary SMS message. The copy of the Whisper example running on the other emulator descrypts and displays the message.
The Whisper example uses a Rijndael cipher with a 128-bit key. The Bouncy Castle APIs include several different implementations of Rijndael. I chose the one that's supposed to use the least memory,
After the cipher is initialized with the appropriate key, encrypting the message is easy (see SendTask.java in the source code download). To foil cryptanalysis, a random block of initialization data is prepended to the message itself to put the cipher into an unpredictable state.
On the receiving end, it's just as easy to decrypt the incoming message. See the The Whisper example does not check the integrity of the transmitted data. If the ciphertext is modified as it passes through the network, it will decrypt into unreadable garbage. The recipient being able to read the message at all is an indication that the message is legitimate. If the Whisper example transmitted data a human could not validate, I'd use a checksum or message digest to check the integrity of the data. Key Management is Always a BearThe hard part in this application (and, indeed, any application that uses cryptography) is key management. The Whisper example makes things really easy for the user by building keys into the application itself--but that convenience comes at a cost. The Whisper example is designed to be configured at deployment time for groups of two or more people. For this article, two versions of the Whisper example were created, one for Viktor, one for Fleur. To a Whisper example user, other users are peers. Peers are listed in the application descriptor by name and number. Viktor's application descriptor, contains a single entry that describes Fleur: Whisper-Peer-1: Fleur|5550001 When Viktor's copy of the Whisper example initializes, it finds out about Fleur by examining the descriptor. Then it tries to load the key that will be used for communicating with Fleur from a resource file. In Viktor's MIDlet suite JAR, this file is Peer-5550001.key. Fleur's copy of the Whisper example contains a corresponding entry and key for Viktor. In the Whisper example, each key is owned, not by a single user, but by a pair of peers. Viktor and Fleur share a single key between them. When he writes a message to her, he uses this key to encrypt the message, and she uses the same key to decrypt it. If Luciano, Placido, and Jose wanted to use the Whisper example,
In cryptography terms, the keys are not true secret keys, but shared keys. If you want to use this application, you have to trust your peers to be careful about keeping their keys safe. If I hoped to sell the Whisper example as a real application, I would set up a server with a simple web interface, where users could enter names and numbers and the server would generate keys and package up individualized versions of the Whisper example for each person. Care must be taken in distributing the binaries because they include the keys. The normal distribution method for MIDlet suites is HTTP, which is not secure. An eavesdropper could easily extract the shared keys from the binaries as they were transmitted over the network, then use those keys to decrypt messages intercepted later. One way to keep the keys safe would be to distribute the binaries using HTTPS. Another would be to use HTTP to download the binaries, but use HTTPS to download the keys to the Whisper example client seperately. Building the Source CodeBuilding the Whisper example is very similar to building the example for the preceding article in this series. You'll need both the Ant build tool and the ProGuard obfuscator. If you want to create personalized versions of the Whisper example, as I did for Viktor and Fleur, you'll need to edit the descriptors yourself and make sure that the appropriate key files are present in the project's res directory. If you'd like to generate new keys, that's easy enough too. All you need to do is write out random data to a file. Bear in mind that there's some subtlety to generating random data; for more information, see my own Java Cryptography or Bruce Schneier's comprehensive Applied Cryptography. The Whisper example expects 128-bit keys (a 16-byte file) but you could modify the application to use 192-bit or 256-bit keys instead. SummaryComputer applications need encryption to provide data confidentiality. Most applications will be able to use TLS or HTTPS for encryption, but in other cases you will need to provide your own implementation. Encryption is surprisingly easy, and surpisingly compact, if you use the Bouncy Castle APIs. The obfuscated Whisper example is only about 15 KB. The difficult part of the Whisper example is key management. A web application would simplify the configuration and distribution of the Whisper example. | |||||||||||||||||||||
|
| ||||||||||||