J2ME文本加密-javax.crypto.IllegalBlockSizeException

J2ME文本加密-javax.crypto.IllegalBlockSizeException,java,encryption,java-me,midp,Java,Encryption,Java Me,Midp,我使用DES算法来加密/解密我的文本。它与拉丁语文本配合得很好 但当我开始加密/解密西里尔文时,解密后的文本显示为????????在我的TextField表单和控制台中。我怎样才能修好它 在我更改inputBytes=textToEnrypt.getBytes()之后toinputBytes=textToEnrypt.getBytes(“UTF-8”)

我使用DES算法来加密/解密我的文本。它与拉丁语文本配合得很好

但当我开始加密/解密西里尔文时,解密后的文本显示为????????在我的
TextField
表单和控制台中。我怎样才能修好它

在我更改
inputBytes=textToEnrypt.getBytes()之后
to
inputBytes=textToEnrypt.getBytes(“UTF-8”)
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);
    }
}
我的猜测是(如果您不展示一些代码,我将无法做更多的事情)您正在使用没有参数的
getBytes()
,并从没有参数的
byte[]
构造
字符串。这意味着使用平台默认编码,如果不能表示西里尔字母,那么这就是你得到的

最好对这两种转换都使用UTF-8,这样可以表示每个Unicode字符。

我的猜测是(如果不显示一些代码,我无法做更多的事情)您使用的是没有参数的
getBytes()
,并且从没有参数的
字节[]
构造
字符串。这意味着使用平台默认编码,如果不能表示西里尔字母,那么这就是你得到的


两种转换最好都使用UTF-8,这样可以表示每个Unicode字符。

一个问题是行

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

在加密方法中。不能将
String
用作二进制数据的容器。除非有必要,否则不应将加密数据转换为字符串,然后需要使用适当的编解码器,如base64。

一个问题是行

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

在加密方法中。不能将
String
用作二进制数据的容器。除非有必要,否则不应将加密数据转换为字符串,然后需要使用适当的编解码器,如base64。

DES使用64位(8字节)的块大小。您必须确保加密的数据是8字节的倍数,即用零字节或其他任何方式填充数据,以确保数据是8字节的倍数。否则您将获得非法BlockSizeException。您需要在将字符串转换为UTF-8后执行此操作,当然……

DES使用64位(8字节)的块大小。您必须确保加密的数据是8字节的倍数,即用零字节或其他任何方式填充数据,以确保数据是8字节的倍数。否则您将获得非法BlockSizeException。您需要在将字符串转换为UTF-8后执行此操作,当然……

我可以通过以下更改使其正常工作

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

我能够通过以下更改使其工作

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

谢谢你的回答!但现在我有另一个问题——javax.crypto.IllegalBlockSizeException。我在主题中描述了它。谢谢你的回答!但现在我有另一个问题——javax.crypto.IllegalBlockSizeException。我在主题中描述了它。