但是应该怎么处理的,同样的程序对于英文是合法的,对于中文,出现 “Input length not multiple of 8 bytes”的错误。
"Input length not multiple of 8 bytes",错误提示是因为你所提供的待加密数据位数长度不是8的整数倍。DES加密要求待加密数据byte长度必须为8的整数倍(因为DES密钥的长度为8bytes=64bits),对于不足位数的,可以采用Padding方式进行补位,补足8的倍数后就可以正常操作了
我的部分代码如下(其中已对位数做过判断): // This is where the actual JCA/JCE data encryption takes place. public String getEncryptedData(String data) { String clearData = new String(data); String cipherDataBase64 = null; try { //padding the last byte with " " int pad = clearData.length()%8; for(int i=0;i<(8-pad);i++) clearData += " "; // Creating a Cipher Object. Cipher cipherObj = Cipher.getInstance(this.algoName+"/CBC/NoPadding"); // Initializing the Cipher Object in encryption mode. cipherObj.init(Cipher.ENCRYPT_MODE,this.encKey); // Retreiving the IV(initilization Vector) byte [] iv = cipherObj.getIV(); //Ciphering the clear text. byte[] cipherTemp = cipherObj.doFinal(clearData.getBytes()); //Prefixing the IV to the cipher string to produce cipherData int ivlen = iv.length; int cTlen = cipherTemp.length; int cDlen = ivlen+cTlen ; byte [] cipherData = new byte[cDlen]; // First 8 bytes are IV bytes for (int i=0;i<ivlen;i++) cipherData[i] = (byte)iv[i]; // Rest of the bytes are cipher bytes for (int i=ivlen;i<cDlen;i++) cipherData[i] = (byte)cipherTemp[i-8]; //Base 64 encoding of cipherData cipherDataBase64 = getBase64Encoded(cipherData); } catch (Exception e) { System.out.println("Problem in getEncryptedData()"); e.printStackTrace(); } return cipherDataBase64; }// End getEncryptedData()
// This is where the actual JCA/JCE data encryption takes place.
public String getEncryptedData(String data) {
String clearData = new String(data);
String cipherDataBase64 = null;
try {
//padding the last byte with " "
int pad = clearData.length()%8;
for(int i=0;i<(8-pad);i++)
clearData += " ";
// Creating a Cipher Object.
Cipher cipherObj = Cipher.getInstance(this.algoName+"/CBC/NoPadding");
// Initializing the Cipher Object in encryption mode.
cipherObj.init(Cipher.ENCRYPT_MODE,this.encKey);
// Retreiving the IV(initilization Vector)
byte [] iv = cipherObj.getIV();
//Ciphering the clear text.
byte[] cipherTemp = cipherObj.doFinal(clearData.getBytes());
//Prefixing the IV to the cipher string to produce cipherData
int ivlen = iv.length;
int cTlen = cipherTemp.length;
int cDlen = ivlen+cTlen ;
byte [] cipherData = new byte[cDlen];
// First 8 bytes are IV bytes
for (int i=0;i<ivlen;i++)
cipherData[i] = (byte)iv[i];
// Rest of the bytes are cipher bytes
for (int i=ivlen;i<cDlen;i++)
cipherData[i] = (byte)cipherTemp[i-8];
//Base 64 encoding of cipherData
cipherDataBase64 = getBase64Encoded(cipherData);
}
catch (Exception e) {
System.out.println("Problem in getEncryptedData()");
e.printStackTrace();
}
return cipherDataBase64;
}// End getEncryptedData()
import java.io.*;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;public class a
{
static void main(String args[])
{
try
{
Key key = KeyGenerator.getInstance("DES").generateKey();
Cipher enc = Cipher.getInstance("DES/CBC/NoPadding");
enc.init(Cipher.ENCRYPT_MODE, key);
byte[] input = "测试123412345678".getBytes();
byte[] result = enc.doFinal(input);
System.out.println(result.length); Cipher dec = Cipher.getInstance("DES/CBC/NoPadding");
IvParameterSpec Iv = new IvParameterSpec(enc.getIV());
dec.init(Cipher.DECRYPT_MODE, key, Iv);
System.out.println(new String(dec.doFinal(result)));
} catch (Exception e)
{
e.printStackTrace();
}
}
}这个应该是你期望的流程了。没有问题。
还不对就检查一下你的jce版本,我的是1.2.2你的pad也很古怪,要求在byte上padding,而不是String上。String如果按unicode处理,不能期望汉字长度和转换成的byte相同。另外如果长度是是8的倍数,你还要pad 8个空格,看看你的代码。