J2ME text encryption - javax.crypto.IllegalBlockSizeException
I use DES algorithm to encrypt/decrypt my text. And it works perfect with latin texts.
But when I start encrypt/decrypt cyrillic text, decrypted one is shown as ????? ???????? in my TextField
form and in console. How can i fix it?
After Joachim Sauer advice I changed inputBytes = textToEnrypt.getBytes();
to inputBytes = textToEnrypt.getBytes("UTF-8");
and now I have javax.crypto.IllegalBlockSizeException. Help me, please...
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 开发者_如何学JAVAkey = 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);
}
}
I was able to make it work with the following changes.
Change the return type of encrypt method, from void
to 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;
}
Instead of:
String str = new String(outputBytes, 0, cypheredBytes);
buffer = str;
System.out.println("Encrypted string = " + str);
My guess (and I can't do more without you showing some code) is that you're using getBytes()
without a parameter and construct the String
from the byte[]
without a parameter as well. That means using the platform default encoding and if that can't represent cyrillic characters, then that's what you get.
It's better to use UTF-8 for both transformations, this way you can represent every Unicode character.
DES uses a 64-bit (8-byte) block size. You have to make sure that the data you're encrypting is a multiple of 8 bytes, i.e. pad it out with zero bytes or whatever to ensure that it is. Otherwise you'll get an IllegalBlockSizeException. You'll need to do this after you convert the string to UTF-8, of course....
One problem is the line
String str = new String(outputBytes, 0, cypheredBytes);
in your encrypt method. You cannot use String
as a container for binary data. Encrypted data should not be converted to a String unless it is a requirement, and then you need to use an appropriate codec such as base64.
精彩评论