Search code examples
javaphpblackberryaes

Unable to decrypt AES's ciphertext of php code in blackberry


i m writing one application which encrypt and decrypt data using AES (ECB) mode. Encrypted data of blackberry code successfully decrypt by php code. but problem is that when i get encrypted text from php i m not able to decrypt it with blackberry code..even i m not getting any exception.

here is my code to encrypt and decrypt text.

public static  byte[] encrypt( byte[] keyData, byte[] data )
throws CryptoException, IOException
{
    // Create the AES key to use for encrypting the data.
    // This will create an AES key using as much of the keyData
    // as possible.
    AESKey key = new AESKey( keyData );

    // Now, we want to encrypt the data.
    // First, create the encryptor engine that we use for the actual
    // encrypting of the data.
    AESEncryptorEngine engine = new AESEncryptorEngine( key );

    // Since we cannot guarantee that the data will be of an equal block
    // length we want to use a padding engine (PKCS5 in this case).
    PKCS5FormatterEngine fengine = new PKCS5FormatterEngine( engine );

    // Create a BlockEncryptor to hide the engine details away.
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    BlockEncryptor encryptor = new BlockEncryptor( fengine, output );



    encryptor.write( data );

    encryptor.close();
    output.close();


    return output.toByteArray();
}
public static String AESDecryption(byte[] keyData,byte[] cipherText, int dataLength ) throws CryptoException, IOException {

    // Create the input stream based on the ciphertext
    ByteArrayInputStream in = new ByteArrayInputStream( cipherText, 0, dataLength );

    // Now create the block decryptor and pass in a new instance
    // of an AES decryptor engine with the specified block length
    BlockDecryptor cryptoStream = new BlockDecryptor(new AESDecryptorEngine( new AESKey( keyData )), in );

    byte[] T= new byte[dataLength];
    // Read the decrypted text from the AES decryptor stream and
    // return the actual length read

    int length= cryptoStream.read( T );
  String str= new String(T);


  return str;
}

thanks in advance..


Solution

  • Here is the method that accepts key and encrypted data (in the form of byte arrays) and returns the decrypted data in the form of byte array:

    public static byte[] decrypt(byte[] keyData, byte[] ciphertext) 
             throws CryptoException, IOException {
    
        // First, create the AESKey again.
        AESKey key = new AESKey(keyData);
    
        // Now, create the decryptor engine.
        AESDecryptorEngine engine = new AESDecryptorEngine(key);
        // Since we cannot guarantee that the data will be of an equal block length
        // we want to use a padding engine (PKCS5 in this case).
        PKCS5UnformatterEngine uengine = new PKCS5UnformatterEngine(engine);
    
        // Create the BlockDecryptor to hide the decryption details away.
        ByteArrayInputStream input = new ByteArrayInputStream(ciphertext);
        BlockDecryptor decryptor = new BlockDecryptor(uengine, input);
    
        // Now, read in the data.
        byte[] temp = new byte[100];
        DataBuffer buffer = new DataBuffer();
    
        for (;;) {
            int bytesRead = decryptor.read(temp);
            buffer.write(temp, 0, bytesRead);
    
            if (bytesRead < 100) {
                // We ran out of data.
                break;
            }
        }
    
        byte[] plaintext = buffer.getArray();
    
        return plaintext;
    }
    

    Note encryption/decryption does not operate with strings directly. It only work with byte arrays. So as a final action you need to convert decrypted byte array to string using String(byte[] bytes) or String(byte[] bytes, String enc) constructor. The second constructor can be useful if your string were encoded with any other than "ISO-8859-1" encoding (which is a default one for BlackBerry).

    UPDATE:

    As it turns out you don't use PKCS5 padding on server side AND you convert encrypted byte data into a HEX string, then the solution code is:

    // this is to convert HEX to bytes
    public static byte[] convertHexToBytes(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                                 + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }
    
    // this is the same as initial version, but we don't handle PKCS5 padding here
    public static byte[] decrypt(byte[] keyData, byte[] ciphertext)
            throws CryptoException, IOException {
    
        // First, create the AESKey again.
        AESKey key = new AESKey(keyData);
    
        // Now, create the decryptor engine.
        AESDecryptorEngine engine = new AESDecryptorEngine(key);
    
        // Create the BlockDecryptor to hide the decryption details away.
        ByteArrayInputStream input = new ByteArrayInputStream(ciphertext);
        BlockDecryptor decryptor = new BlockDecryptor(engine, input);
    
        // Now, read in the data.
        byte[] temp = new byte[100];
        DataBuffer buffer = new DataBuffer();
    
        for (;;) {
            int bytesRead = decryptor.read(temp);
            buffer.write(temp, 0, bytesRead);
    
            if (bytesRead < 100) {
                // We ran out of data.
                break;
            }
        }
    
        byte[] plaintext = buffer.getArray();
    
        return plaintext;
    }
    
    // and finally :)
    String key =       "1234567890123456";
    String encrypted = "48b983c4f1575280d244b74cf689efe5";
    
    byte[] keyBytes = key.getBytes();
    byte[] encryptedBytes = convertHexToBytes(encrypted);
    
    // displays "nirav bhandari"
    Dialog.inform(new String(decrypt(keyBytes, encryptedBytes)));