我使用 DES 算法来加密/解密我的文本。它与拉丁文本完美配合。
但是当我开始加密/解密西里尔文本时,解密的文本显示为 ?????我的TextField
表单和控制台中的。我该如何解决?
在Joachim Sauer advice之后我将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);
}
}
答案 0 :(得分:2)
我的猜测(如果没有显示某些代码,我就无法做得更多)就是你在没有参数的情况下使用getBytes()
并在没有参数的情况下从String
构建byte[]
参数也是如此。这意味着使用平台默认编码,如果不能代表西里尔字符,那就是你得到的。
最好将UTF-8用于两种转换,这样就可以表示每个Unicode字符。
答案 1 :(得分:2)
DES使用64位(8字节)块大小。你必须确保你正在加密的数据是8个字节的倍数,即用零字节或其他任何东西填充它以确保它是。否则你会得到一个IllegalBlockSizeException。在将字符串转换为UTF-8之后,您需要执行此操作,当然......
答案 2 :(得分:2)
我能够使其与以下更改一起使用。
将加密方法的返回类型从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);
答案 3 :(得分:1)
一个问题是行
String str = new String(outputBytes, 0, cypheredBytes);
加密方法中的。您不能将String
用作二进制数据的容器。除非是加密数据,否则不应将加密数据转换为字符串,然后需要使用适当的编解码器,例如base64。