Guía de desarrollo

Local Navigation

Motores de sistema de cifrado

Los motores de sistema de cifrado constituyen una alternativa a las factorías de sistema de cifrado (la clase EncryptorFactory). La clase EncryptorFactory se basa en motores. Tanto los motores como las factorías producen resultados idénticos.

Los motores le permiten acceder a los algoritmos de forma directa, así como al nivel más bajo de abstracción. Por ejemplo, podría utilizar la clase DESEncryptorEngine para acceder directamente al algoritmo DES, pasando una matriz de bytes de texto sin formato y recibiendo otra matriz de bytes cifrados.

Todas las clases de motor derivan de la interfaz net.rim.device.api.crypto.BlockEncryptorEngine.

Los siguientes ejemplos de código muestran los dos enfoques principales a la hora de utilizar los motores de sistema de cifrado: un enfoque basado en bloques, en el que se utiliza un motor de sistema de cifrado para cifrar bloques de datos, y un enfoque basado en flujo, en el que se utiliza un sistema de cifrado de bloques para cifrar un flujo de datos.

Ejemplo de código: cifrar bloques de datos mediante un motor de sistema de cifrado

En el modo ECB, el motor acepta un bloque de una vez y también devuelve un bloque de una vez. No existe encadenamiento ni dependencia de otros bloques para el cifrado del texto cifrado. Éste no es el modo más seguro para llevar a cabo el proceso de cifrado. No obstante, se trata del enfoque más sencillo.

El siguiente código de ejemplo utiliza la clase DESEncryptorEngine. Muestra cómo cifrar datos mediante DES y un algoritmo de bloque en modo ECB. En primer lugar se define la entrada y, posteriormente, se define la salida. A continuación, el código crea una nueva clave DES con los datos dados y, posteriormente, se crea el motor. Por último, cifra la entrada con una compensación de cero.

Nota: En este ejemplo se presupone que los caracteres son lo suficientemente bajos en el conjunto de caracteres de Unicode como para tener un punto de código inferior a 256 (siendo necesario un único valor de bytes), de forma que la cifra correspondiente a la longitud de matriz de bytes se corresponda con la del número de caracteres. Esta situación no se da siempre cuando se utilizan conjuntos de caracteres como el árabe, el cirílico y el chino.
// Input.
byte[] input = { 'T','e','s','t','i','n','g','!' };
// Output.
byte[] output = new byte[ 8 ];
byte[] keyData = { (byte)0x01, (byte)0x23, (byte)0x45,(byte)0x67,
                   (byte)0x89, (byte)0x01, (byte)0x23, (byte)0x45 };
// Create a new DES key with the given data.
DESKey key = new DESKey( keyData );
// Create engine.
DESEncryptorEngine engine = new DESEncryptorEngine( key );
// Encrypt the input with offset of zero.
engine.encrypt( input, 0, output, 0);
System.out.println("Ciphertext = " + new String( output ) + ".");

El siguiente código de ejemplo muestra cómo descifrar datos mediante un algoritmo de bloque. Este ejemplo utiliza la clase DESDecryptorEngine para llevar a cabo el proceso de descifrado.

// Input.
byte[] input = { (byte)0x77, (byte)0xFB, (byte)0xF4, byte)0x94,(byte)0xE9,
                 (byte)0x70, (byte)0xDD, (byte)0x0B };
// Output.
byte[] output = new byte[ 8 ];
// Key data from encryption.
byte[] keyData = { (byte)0x01,(byte)0x23, byte)0x45, byte)0x67, (byte)0x89,
                   (byte)0x01, (byte)0x23, (byte)0x45 };
// Create a new DES key with the given data.
DESKey key = new DESKey( keyData );
// Create engine.
DESDecryptorEngine engine = new DESDecryptorEngine( key );
// Decrypt the input with offset of zero.
engine.decrypt( input, 0, output, 0);
System.out.println("Plaintext = " + new String( output ) + ".");

Ejemplo de código: cifrar flujos de datos mediante un motor de sistema de cifrado

El siguiente ejemplo de código utiliza el modo CBC. Este enfoque resulta más engorroso y lento de escribir que el ejemplo anterior. No obstante, devuelve resultados más claros y fiables.

Este enfoque utiliza un vector de inicialización. El vector de inicialización es una matriz de bytes de datos aleatorios que se utiliza para agregar aleatoriedad a los datos generados. Los vectores de inicialización pueden utilizarse con algunos modos de cifra de bloque, como es el caso del modo CBC, con el fin de garantizar que en caso de que un mismo mensaje de texto sin formato se cifre dos veces, el proceso no dará lugar a un mismo mensaje de texto cifrado dos veces.

Este enfoque de cifrado utiliza un sistema de cifrado BlockEncryptor para cifrar un flujo de datos con DES. El cifrado real se lleva a cabo con la llamada a write(). La función del código es la configuración o desinstalación de los sistemas de cifrado y de los motores.

//Input.
byte[] input = { (byte)'T', (byte)'h', (byte)'i', (byte)'s',
                 (byte)' ', (byte)'i', (byte)'s', (byte)' ',
                 (byte)'a', (byte)' ', (byte)'t', (byte)'e',
                 (byte)'s', (byte)'t', (byte)'!', (byte)'!' };
//Initialization vector.
byte[] iv = { (byte)0xFF, (byte)0xFE, (byte)0xFD, (byte)0xFC,
              (byte)0xFB, (byte)0xFA, (byte)0xF9, (byte)0xF8 };
//Key data.
byte[] keyData = { (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67,
                   (byte)0x89, (byte)0x01, (byte)0x23, (byte)0x45 };
// Create a new DES key with the given data.
DESKey key = new DESKey( keyData );
// Create the DES Engine.
DESEncryptorEngine desEngine = new DESEncryptorEngine( key );
// Create the CBC engine.
CBCEncryptorEngine cbcEngine = new CBCEncryptorEngine(desEngine, new InitializationVector(iv));
// Create a stream to hold the encrypted data.
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
// Create the Encryptor using the CBCEncryptorEngine and the output stream.
BlockEncryptor encryptor = new BlockEncryptor( cbcEngine, outputStream );
// Write out the data to encrypt.
encryptor.write( input, 0, input.length );
// Close the encryptor and grab the bytes.
encryptor.close();
byte[] output = outputStream.toByteArray();
System.out.println("Ciphertext = " + new String( output ) + ".");

El siguiente código utiliza BlockDecryptor para descifrar un flujo de datos con DES. Este ejemplo muestra el proceso de descifrado de DES en modo CBC.

//Input
byte[] input = { (byte)0x58, (byte)0x47, (byte)0x50, (byte)0x34,
                 (byte)0x9F, (byte)0xEF, (byte)0x0D, (byte)0x77,
                 (byte)0x31, (byte)0x4E, (byte)0xB7, (byte)0x73,
                 (byte)0x56, (byte)0xAC, (byte)0x3C, (byte)0xD6 };
//Initialization vector.
byte[] iv = { (byte)0xFF, (byte)0xFE, (byte)0xFD, (byte)0xFC,
              (byte)0xFB, (byte)0xFA, (byte)0xF9, (byte)0xF8 };
//Output.
byte[] output = new byte[ 16 ];
//Key data.
byte[] keyData = { (byte)0x01, (byte)0x23, (byte)0x45, (byte)0x67,
                   (byte)0x89, (byte)0x01, (byte)0x23, (byte)0x45 };
// Create a new DES key with the given data.
DESKey key = new DESKey( keyData );
// Create the DES Engine.
DESDecryptorEngine desEngine = new DESDecryptorEngine( key );
// Create the CBC engine.
CBCDecryptorEngine cbcEngine = new CBCDecryptorEngine(desEngine, new InitializationVector(iv));
// Create a stream from the input byte array.
ByteArrayInputStream inputStream = new ByteArrayInputStream( input );
// Create the Decryptor using the CBCDecryptorEngine.
BlockDecryptor decryptor = new BlockDecryptor( cbcEngine, inputStream );
// Read in the decrypted data.
int ret = decryptor.read( output, 0, output.length );
// Close the encryptor and grab the bytes.
decryptor.close();
inputStream.close();
System.out.println("Plaintext = " + new String( output ) + ".");
Tema siguiente: Gestionar excepciones

¿Le ha resultado útil esta información? Envíenos sus comentarios.