J2ME шифрование текста - javax.crypto.IllegalBlockSizeException - PullRequest
1 голос
/ 04 февраля 2011

Я использую DES алгоритм для шифрования / дешифрования моего текста. И он отлично работает с латинскими текстами.

Но когда я начинаю шифровать / дешифровать кириллический текст, дешифрованный отображается как ????? ???????? в моей TextField форме и в консоли. Как я могу это исправить?

После Совет Йоахима Зауэра Я изменил inputBytes = textToEnrypt.getBytes(); на inputBytes = textToEnrypt.getBytes("UTF-8");, и теперь у меня есть javax.crypto.IllegalBlockSizeException . Помогите мне, пожалуйста ...

package crypting;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.microedition.midlet.*;

public class Encryptor extends MIDlet {

    String buffer;

    public void startApp() {
        String keyString = "testtest";
//        encrypt("Text for encrypting", keyString);
        encrypt("Привет", keyString);
        decrypt(buffer, keyString);
    }

    public void pauseApp() {
    }

    public void destroyApp(boolean unconditional) {
    }

    public void encrypt(String textToEnrypt, String keyString) {
        Cipher cipher;
        try {
            cipher = Cipher.getInstance("DES");
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return;
        }

        byte[] keyData = keyString.getBytes();
        SecretKeySpec key = new SecretKeySpec(keyData, 0, keyData.length, "DES");

        try {
            cipher.init(Cipher.ENCRYPT_MODE, key);
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return;
        }

        int cypheredBytes = 0;

        byte[] inputBytes;
        try {
            inputBytes = textToEnrypt.getBytes("UTF-8");
//            inputBytes = textToEnrypt.getBytes();
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return;
        }

        byte[] outputBytes = new byte[100];

        try {
            cypheredBytes = cipher.doFinal(inputBytes, 0, inputBytes.length,
                    outputBytes, 0);
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return;
        }

        String str = new String(outputBytes, 0, cypheredBytes);
        buffer = str;
        System.out.println("Encrypted string = " + str);
    }


    public void decrypt(String textToDecrypt, String keyString) {
        Cipher cipher;
        try {
            cipher = Cipher.getInstance("DES");
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return;
        }

        byte[] keyData = keyString.getBytes();
        SecretKeySpec key = new SecretKeySpec(keyData, 0, keyData.length, "DES");

        try {
            cipher.init(Cipher.DECRYPT_MODE, key);
        } catch (Exception ex) {
            System.out.println("2. " + ex.toString());
            return;
        }

        int cypheredBytes = 0;

        byte[] inputBytes;
        try {
            inputBytes = textToDecrypt.getBytes("UTF-8");
//            inputBytes = textToDecrypt.getBytes();
        } catch (Exception ex) {
            System.out.println("3. " + ex.toString());
            return;
        }

        byte[] outputBytes = new byte[100];

        try {
            cypheredBytes = cipher.doFinal(inputBytes, 0, inputBytes.length,
                    outputBytes, 0);
        } catch (Exception ex) {
            System.out.println("4. " + ex.toString());
            return;
        }

        String str = new String(outputBytes, 0, cypheredBytes);
        System.out.println("Decrypted string = " + str);
    }
}

Ответы [ 4 ]

2 голосов
/ 28 марта 2011

Мне удалось заставить его работать со следующими изменениями.

Измените тип возврата метода encrypt с void на byte[]:

static public byte[] encrypt(String textToEnrypt, String keyString)
  throws Exception
{
    //at the end
    //write this down:
    byte[] newResponse = new byte[cypheredBytes];
    for(int i=0;i < cypheredBytes;i++)
    {
        newResponse[i] = outputBytes[i];
    }
    return newResponse;
}

Вместо:

String str = new String(outputBytes, 0, cypheredBytes);
buffer = str;
System.out.println("Encrypted string = " + str);
2 голосов
/ 04 февраля 2011

DES использует 64-битный (8-байтовый) размер блока.Вы должны убедиться, что данные, которые вы шифруете, кратны 8 байтам, т. Е. Дополнить их нулевыми байтами или чем-то еще, чтобы обеспечить это.В противном случае вы получите исключение IllegalBlockSizeException.Конечно, вам нужно будет это сделать после преобразования строки в UTF-8 ....

2 голосов
/ 04 февраля 2011

Полагаю (и я не смогу сделать больше без показа кода), вы используете getBytes() без параметра и также строите String из byte[] без параметра.Это означает использование кодировки платформы по умолчанию, и если она не может представлять кириллические символы, то это то, что вы получаете.

Лучше использовать UTF-8 для обоих преобразований, таким образом вы можете представлять каждый символ Unicode.

1 голос
/ 04 февраля 2011

Одной из проблем является строка

String str = new String(outputBytes, 0, cypheredBytes);

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

...