Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
Highlighted
New Contributor
Posts: 8
Registered: ‎09-01-2010
My Device: Not Specified

PBEWithMD5AndDES in Blackberry - getBytes problem

[ Edited ]

Hi,

I'm developing an application with Blackberry JDE 4.2.1 and I need to encode some data with the standard Java Password-based Encoding, MD5 and DES algorithms.

In JavaSE it can be done easily with the Standard API. I found a port in C# and I'm trying to recode it again for J2ME.

Emulating PBEWithMD5AndDES Encryption under .NET

Following this example I create a 16 byte array mixing an String literal seed and a 8-byte array salt.

Then i hash the array 19 times with MD5 and finally divide it again in:
- 8 bytes for the DES Key
- 8 bytes for the InitializationVector

 

Here I show the code which generates the hash and divides it in Key and IV for the DES cypher

 

/*
 * The keyString contains the seed to be mixed with the salt
 * The salt contains the following values: byte[] SALT = { (byte)0xA9, (byte)0x9B, (byte)0xC8, (byte)0x32, (byte)0x56, (byte)0x35, (byte)0xE3, (byte)0x03 };
 * md5Interations is the number of times (19) the keyString+salt will be hashed in MD5
 * Segments is 0
 */
public void generate( String keyString, int[] salt, int md5Iterations, int segments)
{  
  try
  {
    int HASHLENGTH = 16;
    byte[] keymaterial = null;            
    String keyStringUTF8 = new String(keyString.getBytes(), "UTF-8");        
    int [] psbytes = new int[keyString.length()]; //psbytes contains the seed coming from the keyString param
    for(int i=0; i < keyStringUTF8.length(); i++)            
        psbytes[i] = (int)keyStringUTF8.charAt(i);            

    int[] data00 = new int[psbytes.length + salt.length];

    System.arraycopy(psbytes, 0, data00, 0, psbytes.length);
    System.arraycopy(salt, 0, data00, psbytes.length, salt.length);                        

    int[] result = null;
    int[] hashtarget = new int[HASHLENGTH + data00.length];

    for(int j=0; j<segments; j++)
    {
        if ( j == 0)
            result = data00; //With segments=0, result will always contain psbytes + salt in a 16 byte array
        else
        {
            System.arraycopy(result, 0, hashtarget, 0, result.length);
            System.arraycopy(data00, 0, hashtarget, result.length, hashtarget.length);
            result = hashtarget;
        }                
		// Here is where the problem begins. I have the correct decimal values in the int array and I need to transform them to byte for the MD5 hashing.
        byte[] resultadoMD5 = HexUtil.convertirIntEnBytes(result); //Converts int[] into byte[]. Code shown before this method

        for(int i=0; i < md5Iterations; i++)
        {
            MD5 md5 = new MD5(resultadoMD5);
            byte[] resultado = md5.doFinal();
            String hash = md5.toHex(resultado); // The hash string contains 16 characters
            resultadoMD5 = hash.getBytes(); // this getBytes returns 32 bytes
        }
        keymaterial = new byte[resultadoMD5.length];
        System.arraycopy(resultadoMD5, 0, keymaterial, j * HASHLENGTH, result.length);
    }
    System.arraycopy(keymaterial, 0, _key, 0, 8);
    System.arraycopy(keymaterial, 8, _iv, 0, 8);
  }
  catch ( Exception e)
  {
    System.out.println("Excepcion en PKCSKeyGenerator.generate(): " + e.getMessage());
  }
}

public static byte[] convertirIntEnBytes(int[] intBytes)
{
  byte[] resultado = null;
  try
  {
    resultado = new byte[intBytes.length];
    for(int i=0; i<intBytes.length; i++)
    {
      resultado[i] = (byte)intBytes[i];
    }
  }
  catch ( Exception e)
  {
    System.out.println("Excepcion en HexUtil.convertirIntEnBytes(): " + e.getMessage());
  }
  return resultado;
}

 

 


Firstly I had a problem mixing the initial seed & salt cause I obtained the initial values from C# and the "byte" representation differs in Java (-128 .. 127) and C# ( 0 ... 255).

I solved it looping through the SALT hex characters and converting them to decimal, so I decided to work with int arrays instead of byte arrays.

Once I have the int array with the salt and the seed mixed, I need to transform it to bytes again to hash it in MD5. I loop throught the array and transform each int into byte, getting a 16 byte array.

Then I hash it to MD5 and here is when the problem starts. When I invoke the getBytes() method, instead of getting a 16 byte array, I get a 32 byte array, so the MD5 differs from the one generated in C#

 

I'm not used to work with bytes in j2me and this difference betwen java's signed bytes and C#'s unsigned bytes is a real pain. The cypher API classes I use from blackberry work mostly with byte arrays and I can't find a clean way to solve this problem. Any clue?

 

Thanks in advance