#ff0000 28  2005 . - #000655    J2ME
#def   J2ME      ,      .  MIDP 1.0       HTTPS,        .        .        . ,      Palm OS , ,   MIDP,         Palm OS. MIDP   ,          . ,      MIDP  Palm OS   .       . 

 ,      CDC  CLDC.      /,     .       .     . 

Legion of the Bouncy Castle   Java ,       .       J2SE,    ,     J2ME.   lightweight API   CLDC   CLD. Lightweight API       ,   DES, Blowfish, IDEA, Rijndael  RC4;      .   ,        J2ME. 

  API,   Bouncy Castle     lightweight API for J2ME.     - .    ,   midp_classes.zip    ,        ,    Bouncy Castle    ,     CLDC  MIDP.  ,           . 

    ,  Bouncy Castle lightweight API. 

import org.bouncycastle.crypto.*;
import org.bouncycastle.crypto.engines.*;
import org.bouncycastle.crypto.modes.*;
import org.bouncycastle.crypto.params.*;

//    Bouncy Castle
// lightweight API,    
//   DES

public class Encryptor {

    private BufferedBlockCipher cipher;
    private KeyParameter key;
    
    //  .
    //       8 .

    public Encryptor( byte[] key ){
        cipher = new PaddedBlockCipher(
                    new CBCBlockCipher(
                       new DESEngine() ) );

        this.key = new KeyParameter( key );
    }

    //  .
    //       8 aaeo.

    public Encryptor( String key ){
        this( key.getBytes() );
    }

    // ,   .

    private byte[] callCipher( byte[] data )
                        throws CryptoException {
        int size = 
                   cipher.getOutputSize( data.length );
        byte[] result = new byte[ size ];
        int olen = cipher.processBytes( data, 0,
                              data.length, result, 0 );
        olen += cipher.doFinal( result, olen );

        if( olen < size ){
            byte[] tmp = new byte[ olen ];
            System.arraycopy( 
                             result, 0, tmp, 0, olen );
            result = tmp;
        }

        return result;
    }
    //    .
    //     .

    public synchronized byte[] encrypt( byte[] data )
                  throws CryptoException {
        if( data == null || data.length == 0 ){
            return new byte[0];
        }

        cipher.init( true, key );
        return callCipher( data );
    }

    //  

    public byte[] encryptString( String data )
                  throws CryptoException {
        if( data == null || data.length() == 0 ){
            return new byte[0];
        }

        return encrypt( data.getBytes() );
    }

    // 

    public synchronized byte[] decrypt( byte[] data )
                  throws CryptoException {
        if( data == null || data.length == 0 ){
            return new byte[0];
        }

        cipher.init( false, key );
        return callCipher( data );
    } 
    //  , 
    //  encryptString.

    public String decryptString( byte[] data )
                    throws CryptoException {
        if( data == null || data.length == 0 ){
            return "";
        }

        return new String( decrypt( data ) );
    }
}

  ,      .   DESEngine -  56- DES : 

public Encryptor( byte[] key ){
        cipher = new PaddedBlockCipher(
                    new CBCBlockCipher(
                       new DESEngine() ) );

 DES   8- .     ,   PaddedBlockCipher  CDCBlockCipher.      "",    .         . 

        callCipher. 

private byte[] callCipher( byte[] data )
                throws CryptoException {
    int size = 
        cipher.getOutputSize( data.length );

  ,          .         ( ). 

Encryptor encryptor = new Encryptor( "ghk23rTX" );

 ,       DES 56-bit,         . 

       encrypt  decrypt.  encryptString  decryptString     . 

    MIDlet-,   Encryptor     ,   .      .       ,  .      . 

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

import org.bouncycastle.crypto.*;

//   / .

public class CryptoTest extends MIDlet {

    private Display display;
    private Command exitCommand =
                         new Command( "Exit",
                                     Command.EXIT, 1 ); 
    private Command okCommand =
                         new Command( "OK",
                                      Command.OK, 1 );

    private Encryptor encryptor;
    private RecordStore rs;

    public CryptoTest(){
    }

    protected void destroyApp( boolean unconditional )
                   throws MIDletStateChangeException {
        exitMIDlet();
    }

    protected void pauseApp(){
    }

    protected void startApp()
                   throws MIDletStateChangeException {
        if( display == null ){ //  ...
            initMIDlet();
        }
    }

    private void initMIDlet(){
        display = Display.getDisplay( this );

        //   

        try {
            rs = RecordStore.openRecordStore( "test",
                                    true );
        }
        catch( RecordStoreException e ){
            //  
        }

        display.setCurrent( new AskForKey() );
    }

    public void exitMIDlet(){
        try {
            if( rs != null ){
                rs.closeRecordStore();
            }
        }
        catch( RecordStoreException e ){
        }

        notifyDestroyed();
    }

    private void displayException( Exception e ){
        Alert a = new Alert( "Exception" );
        a.setString( e.toString() );
        a.setTimeout( Alert.FOREVER );
        display.setCurrent( a, new AskForKey() );
    }

    class AskForKey extends TextBox
                    implements CommandListener {
        public AskForKey(){
            super( "Enter a secret key:", "", 8, 0 );
            setCommandListener( this );
            addCommand( okCommand );
            addCommand( exitCommand );
        }

        public void commandAction( Command c,
                                   Displayable d ){
            if( c == exitCommand ){
                exitMIDlet();
            } 

            String key = getString();
            if( key.length() < 8 ){
                    //    
                Alert a = new Alert( "Key too short" );
                a.setString( "The key must be " +
                             "8 characters long" );
                setString( "" );
                display.setCurrent( a, this );
                return;
            }

            encryptor = new Encryptor( key );

            try {
                if( rs.getNextRecordID() == 1 ){
                    display.setCurrent(
                                  new EnterMessage() );
                } else {
                    byte[] data = rs.getRecord( 1 );
                    String str = 
                       encryptor.decryptString( data );

                    Alert a = 
                        new Alert( "Decryption" );
                    a.setTimeout( Alert.FOREVER );
                    a.setString( 
                        "The decrypted string is '" +
                                 str + "'" );
                    display.setCurrent( a, this );
                }
            }
            catch( RecordStoreException e ){
                displayException( e );
            }
            catch( CryptoException e ){
                displayException( e );
            }
        }
    }

    class EnterMessage extends TextBox
                       implements CommandListener {
        public EnterMessage(){
            super( "Enter a message to encrypt:", "",
                   100, 0 );
            setCommandListener( this );
            addCommand( okCommand );
        }

        public void commandAction( Command c,
                                   Displayable d ){
            String msg = getString();

            try {
                byte[] data =
                      encryptor.encryptString( msg );
                rs.addRecord( data, 0, data.length );
            }
            catch( RecordStoreException e ){
                displayException( e );
            }
            catch( CryptoException e ){
                displayException( e );
            }

            display.setCurrent( new AskForKey() );
        }
    }
}