BlackBerry JDE API Reference: Cryptography API Overview

Cryptography

Overview

This category contains the packages you can use to perform tasks that involve cryptography. You can use this Crypto API to encrypt and decrypt data, work with secure connections, manage cryptographic keys and digitally sign and verify data. Support is included for both assymetric (public key) and symmetric (private key) encryption.

The Crypto API includes the following packages:

The API is comprehensive. It is designed to provide you with high level abstractions to achieve a wide range of cryptographic tasks. However, the API is also designed to be flexible. If the task you need to do is not covered you can extend the API by implementing your own cryptographic algorithms, encoding schemes, certificates and keystores. These tutorials provide walkthroughs describing how to extend the API.

Because the API is large, it is easier to learn and navigate if you view it as a set of smaller component APIs. The next sections describe the categories of tasks covered by components of the API.

Secure Messaging

This component of the API is RIM's implementation of the Cryptographic Message Syntax (CMS) standard. CMS specifies standard cryptographic content types. It describes message and transmission formats for those content types. The S/MIME secure internet mail standard is built upon CMS. This API provides types that make it easy to create and manage CMS content types.

Secure Connections

This component of the API lets you work with secure connections. SSL is the well-known protocol invented by Netscape and used in the implementation of HTTPS. It is designed to secure data sent over TCP/IP connections. It fits in between TCP/IP and higher level protocols like HTTP, FTP and SMTP. TSL is a standard from the IETF meant to replace SSL. It is based on version 3 of SSL and has been widely adopted. WTLS is another protocol that provides secure connections, but WTLS is a layer on top of WAP rather than TCP/IP. Securing wireless communications that utilize WAP involves using WTLS between the client device and the WAP gateway and one of SSL or TSL beyond the WAP gateway. None of these three protocols are compatible; interoperation requires a translation layer.

Key Management

Key Store

A keystore is a database used to store cryptographic keys and digital certificates. This component of the API lets you work with a keystore.

Key Encoding

There are various representations or encodings of cryptographic keys. This component of the API lets convert keys from one encoding to another. Encoding should not be confused with encryption. Keys are encoded to provide a standard representation, not to protect their identity.

Crytographic Primitives

This is the core component of the API and includes encrypting and decrypting algorithms for both private and public key based cryptography. In addition, this component of the API includes data structures and algorithms that support the use of the core encrypting and decrypting algorithms.

Code Sample: Encoding and decoding a message using TripleDES

TripleDES is a popular symmetric key encryption algorithm. The Crypto API makes it easy to use TripleDES to encrypt and decrypt messages.

Click here for a code sample that demonstrates how to encrypt and decrypt a message.

import java.io.*;
import net.rim.device.api.crypto.*;
import net.rim.device.api.util.*;
import net.rim.device.api.ui.*;
import net.rim.device.api.ui.component.*;
import net.rim.device.api.ui.container.*;
import net.rim.device.api.util.*;

public class EncodeDecodeString extends UiApplication implements FieldChangeListener
{
    private ButtonField _encrypt_button;
    private ButtonField _decrypt_button;
    private TripleDESKey _key;
    private TextField _edit_input_string;

    public static void main( String[] args )
    {
        EncodeDecodeString theApp = new EncodeDecodeString();
        theApp.enterEventDispatcher();
    }

    public void fieldChanged(Field field, int context)
    {
        String strCurrentMessage = _edit_input_string.getText();
        if(field == _encrypt_button)
        {
            _edit_input_string.setText(encrypt(strCurrentMessage));
        }
        else
        {
            _edit_input_string.setText(decrypt(strCurrentMessage));
        }
    }


    public EncodeDecodeString()
    {
        MainScreen screen = new MainScreen();
        screen.setTitle(new LabelField("Crypto Demo", LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH));
        
        _edit_input_string = new BasicEditField("Message:", null, 256, BasicEditField.FILTER_DEFAULT);
        screen.add(_edit_input_string);
        
        _encrypt_button = new ButtonField("Encrypt");
        _encrypt_button.setChangeListener(this);
        screen.add(_encrypt_button);
        
        _decrypt_button = new ButtonField("Decrypt");
        _decrypt_button.setChangeListener(this);
        screen.add(_decrypt_button);
       
        pushScreen(screen);
    }

    public String encrypt(String plaintext)
    {
        try 
        {
            _key = new TripleDESKey();
            TripleDESEncryptorEngine encryptionEngine = new TripleDESEncryptorEngine(_key);

            // In most cases, the data that we are going to encrypt will
            // not fit into the block length of a cipher. When that happens, we must use a padding
            // algorithm to pad out the last block. We are going to use PKCS5 to do the padding for us.
            PKCS5FormatterEngine formatterEngine = new PKCS5FormatterEngine( encryptionEngine );

            // Use the byte array output stream to catch the encrypted information.
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

            // Create a block encryptor which will help us use the triple des engine.
            BlockEncryptor encryptor = new BlockEncryptor( formatterEngine, outputStream );

            // Encrypt the actual data.
            encryptor.write( plaintext.getBytes() );

            // Close the stream. This forces the extra bytes to be padded out if there were
            // not enough bytes to fill all of the blocks.
            encryptor.close();

            // Get the actual encrypted data.
            byte[] encryptedData = outputStream.toByteArray();
            String strEncrypted = new String(encryptedData);
            return(strEncrypted);

        } 
        catch( CryptoTokenException e ) 
        {
            System.out.println(e.toString());
        } 
        catch (CryptoUnsupportedOperationException e) 
        {
            System.out.println(e.toString());
        } 
        catch( IOException e ) 
        {
            System.out.println(e.toString());
        }
        return "error";
    }
    
    
    public String decrypt(String ciphertext)
    {
            try
            {
            // We are now going to perform the decryption.  Note that since this is a 
            // symmetric algorithm we want to use the same key as before.
            TripleDESDecryptorEngine decryptorEngine = new TripleDESDecryptorEngine(_key);

            // Create the unformatter engine that will remove any of the padding bytes.
            PKCS5UnformatterEngine unformatterEngine = new PKCS5UnformatterEngine( decryptorEngine );

            // Set up an input stream to hand the encrypted data to the block decryptor.
            ByteArrayInputStream inputStream = new ByteArrayInputStream( ciphertext.getBytes() );

            // Create the block decryptor passing in the unformatter engine and the 
            // encrypted data.
            BlockDecryptor decryptor = new BlockDecryptor( unformatterEngine, inputStream );

            // Now we want to read from the stream. We are going to read the data 10 bytes 
            // at a time and then add that new data to the decryptedData array.  It is 
            // important to note that for efficiency one would most likely want to use a 
            // larger value than 10.  We use a small value so that we can demonstrate 
            // several iterations through the loop.
            byte[] temp = new byte[10];
            DataBuffer db = new DataBuffer();
            
            for( ;; ) 
            {
                int bytesRead = decryptor.read( temp );
                if( bytesRead <= 0 )
                {
                    // We have run out of information to read, bail out of loop.
                    break;
                }
                db.write(temp, 0, bytesRead);
            }

            // Now we want to ensure that the decrypted data is the same as the data we 
            // passed into the encryptor.
            byte[] decryptedData = db.toArray();
            String strDecrypted = new String(decryptedData);
            return(strDecrypted);         
        } 
        catch( CryptoTokenException e ) 
        {
            System.out.println(e.toString());
        } 
        catch (CryptoUnsupportedOperationException e) 
        {
            System.out.println(e.toString());
        } 
        catch( IOException e ) 
        {
            System.out.println(e.toString());
        }
        return "error";
   }
}	

Crypto API Architecture

The following table presents the components of the Crypto API. It includes links to more reference information about each of the component APIs.

Secure Messaging API Secure Connection API
CMS API
TLS API SSL API WTLS API
Key Management API
KeyStore API
KeyStore DeviceKeyStore
SyncableRIMKeyStore RIMKeyStore
PersistableRIMKeyStore TrustedKeyStore
Encoding API
Private Key Encoders Public Key Encoders
Signature Encoders Symmetric Key Encoders
Certificate API
Certificate X509
Status WTLS
ASN.1 API
ASN1InputStream
ASN1OutputStream
ASN1InputByteArray
OID API
OID OIDs
Cryptographic Primitives API
Symmetric Key Algorithms Public Key Algorithms
Miscellaneous
Digests PRNGs
Symmetric Key Algorithms
Keys Encryptors Decryptors MACs

AES
ARC4
Cast128
DES
TripleDES
RC2
RC5
Skipjack
HMAC
Algorithms
AES ARC4
DES TripleDES
RC2 RC5
Skipjack CAST128
Algorithms
AES ARC4
DES TripleDES
RC2 RC5
Skipjack CAST128
CBCMAC
HMAC
Modes
CBC CFB
OFB X
Modes
CBC CFB
OFB X
Padding
PKCS5
Padding
PKCS5
Public Key Algorithms
Keys Key Agreement Encryptors Decryptors Signers Verifiers
DH
DSA
EC
KEA
RSA
DH
ECDH
ECMQV
KEA
RSA PKCS1
RSA OAEP
ElGamal
RSA PKCS1
RSA OAEP
ElGamal
DSA
ECDSA
ECNR
RSA PKCS1
RSA PSS
X9.31
DSA
ECDSA
ECNR
RSA PKCS1
RSA PSS
X9.31
KDFs
P1363 KDF1
X9.42 KDF
Miscellaneous
Digests PRNGs
SHA1 SHA256 SHA384
SHA512 MD2 MD4
MD5 RIPEMD128 RIPEMD160
P1363 KDF1 PKCS1 MGF1
X9.42 KDF PKCS5 KDF1
PKCS5 KDF2 FIPS186 PRNG
RFC 2631 KDF

Copyright 1999-2010 Research In Motion Limited. 295 Phillip Street, Waterloo, Ontario, Canada, N2L 3W8. All Rights Reserved.
Copyright 1993-2003 Sun Microsystems, Inc. 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
Copyright 2002-2003 Nokia Corporation All Rights Reserved.
Java is a trademark or registered trademark of Sun Microsystems, Inc. in the US and other countries.