Проблема расшифровки Java AES - PullRequest
2 голосов
/ 12 октября 2010

Мне было поручено расшифровать файл на Java, который был зашифрован с использованием следующих критериев:

Алгоритм шифрования AES с 128-битным ключом, режим ECB и заполнение PKCS7. Формат зашифрованного файла: - первый байт - шестнадцатеричный 0x31 - указывает используемый метод шифрования (1 для AES) - следуют зашифрованные байты входного файла

Я также должен загрузить файл, поэтому вот моя попытка:

Код загрузки, я пропускаю первый байт здесь, так как он не требуется и не зашифрован:


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) {

        }

    }

Это дает мне загруженный зашифрованный файл, поэтому я затем пытаюсь расшифровать этот файл, используя следующий код:


         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(); 

вышесказанное должно дать мне расшифрованные данные в новом файле.

А вот методы util, использованные в этом коде для создания ключа в байтовом формате для 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));
}

Однако в настоящее время это дает мне следующее исключение:

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

Зашифрованный файл загружается нормально, расшифровка выполняется, но я получаю вышеупомянутое исключение, и проверка файла, который должен быть расшифрован, показывает, что первая строка файла расшифрована правильно, а затем небольшие части следующей пары строк, но затем возвращает ненужную для остальных.

Я застрял в этом сейчас, не зная, где искать проблему, кто-нибудь может помочь? Или укажете мне на то, что может быть причиной исключения?

Дополнительная информация:

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

Приведенная выше строка относится к исключению в журнале cat (stacktrace)

И это показывает, что исключение происходит в этой строке кода:

while ((numRead = inCipher.read(buf)) >= 0) {

1 Ответ

1 голос
/ 12 октября 2010

Без полной трассировки стека трудно отладить, нам пришлось бы перекомпилировать ваш код, если вы не можете опубликовать его здесь по соображениям безопасности (очевидно), попробуйте анализатор стека трассировки, такой как IBM stackanalyzer или lady4j

Анализатор работает для всех видов разработки (включая Android)

...