views:

62

answers:

1

I have been tasked with decrypting a file in Java that has been encrypted using the following criteria:

AES encryption algorithm with 128-bit key, ECB mode and PKCS7 padding. The encrypted file format is: - first byte is hex 0x31 – specifying encryption method used (1 for AES) - followed by the encrypted bytes of the input file

I must also download the file, so here is my attempt so far:

The download code, I skip the first byte here as it is not required and is not encrypted:


final String PATH = "/sdcard/" + IMEI + ".xml";  //put the downloaded file here
        try {
            URL url = new URL(context.getString(R.string.xml_feed) + IMEI + ".xml");
            enc_File = new File(PATH);
            long startTime = System.currentTimeMillis();

            /* Open a connection to that URL. */

            URLConnection ucon = url.openConnection();

            /*
             * Define InputStreams to read from the URLConnection.
             */
            InputStream is = ucon.getInputStream();

            BufferedInputStream bis = new BufferedInputStream(is);

            /*
             * Read bytes to the Buffer until there is nothing more to read(-1).             */

            ByteArrayBuffer baf = new ByteArrayBuffer(50);

            int current = 0;
            bis.skip(1);
            while ((current = bis.read()) != -1) {

                baf.append((byte) current);

            }

            /* Convert the Bytes read to a String. */

            FileOutputStream fos = new FileOutputStream(enc_File);
            fos.write(baf.toByteArray());
            fos.close();

        } catch (IOException e) {

        }

    }

This gives me the encrypted file downloaded, So I then try to decrypt this file using the following code:


         String bytes = toHex("the 16 bit key");
            Key skeySpec = new SecretKeySpec(toByte(bytes), "AES");
            Cipher c = Cipher.getInstance("AES/ECB/PKCS7Padding");  

            byte[] buf = new byte[1024]; 


            // Bytes read from in will be decrypted 

            InputStream inCipher = new FileInputStream(enc_File);
            OutputStream outCipher = new FileOutputStream(cipherFile);
            c.init(Cipher.DECRYPT_MODE, skeySpec);
            inCipher = new CipherInputStream(inCipher, c); // Read in the decrypted bytes and write the cleartext to out 
            int numRead = 0;            

                    while ((numRead = inCipher.read(buf)) >= 0) {
                          outCipher.write(buf, 0, numRead);
                } 
                outCipher.close(); 

the above should give me the decryted data in a new file.

And here are the util methods used in that code to create the Key in Byte format for the SecretKeySpec


public static byte[] toByte(String hexString) {
    int len = hexString.length()/2;
    byte[] result = new byte[len];
    for (int i = 0; i < len; i++)
        result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
    return result;
}

public static String toHex(byte[] buf) {
    if (buf == null)
        return "";
    StringBuffer result = new StringBuffer(2*buf.length);
    for (int i = 0; i < buf.length; i++) {
        appendHex(result, buf[i]);
    }
    return result.toString();
}
private final static String HEX = "0123456789ABCDEF";
private static void appendHex(StringBuffer sb, byte b) {
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}

public static String toHex(String txt) {
    return toHex(txt.getBytes());
}
public static String fromHex(String hex) {
    return new String(toByte(hex));
}

However this currently gives me the following exception:

10-12 11:19:26.337: WARN/System.err(5376): java.io.IOException: last block incomplete in decryption

The encrypted file downloads fine, the decrytption runs but I get the above exception and checking the file that should be decrypted reveals that the first line of the file decrypted properly and then small parts of the next couple of lines but then returns junk for the rest.

I'm stuck at this now not knowing where to look for the problem, can anybody help? Or point me in the direction of what may be causing the exception?

Additional info:

10-12 15:30:37.291: WARN/System.err(6898):     at com.mypackage.net.SettingsProvisioner.getRoutingDoc(SettingsProvisioner.java:217)

The above line is from the exception in the log cat (stacktrace)

And it shows that the exception is occuring at this line of code:

while ((numRead = inCipher.read(buf)) >= 0) {
+1  A: 

Without the full stacktrace it is dificult to debug we would have to recompile your code, if you can not post it here for security reasons (obvious) try a stacktrace analyzer like the IBM stackanalyzer or lady4j

The analyzer works for everykind of development (Android included)

Raul Lapeira Herrero
I'm working on Android so the analyzer's wont work but I have edited my question to include some more info
Donal Rafferty