我有点小问题。当我试图加密文本,然后解密该文本时,我会得到一个错误:
javax.crypto.IllegalBlockSizeException:使用填充密码解密时输入长度必须为16倍
这是我的代码:
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
*
* @author Grzesiek
*/
public class SymmethricCipherCBC {
/* Klucz: */
private byte[] keyBytes = new byte[] {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x00,0x01,0x02,0x03,0x04,0x05
};
/* Wektor inicjalizacyjny: */
private byte[] ivBytes = new byte[] {
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,
0x00,0x01,0x02,0x03,0x04,0x05
};
private Cipher cipher;
private SecretKeySpec keySpec;
private IvParameterSpec ivSpec;
public SymmethricCipherCBC() throws NoSuchAlgorithmException, NoSuchPaddingException{
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //Utworzenie obiektu dla operacji szyfrowania/deszyfrowania algorytmem AES w trybie CBC.
keySpec = new SecretKeySpec(keyBytes, "AES"); // Utworzenie obiektu klucza dla algorytmu AES z tablicy bajtow
ivSpec = new IvParameterSpec(ivBytes); // // Utworzenie obiektu dla wektora inicjalizacyjnego
}
public String encryptText(String plainText) throws NoSuchAlgorithmException,
InvalidKeyException,
NoSuchPaddingException,
InvalidAlgorithmParameterException,
ShortBufferException,
IllegalBlockSizeException,
BadPaddingException,
UnsupportedEncodingException{
int cipherTextLength;
byte[] cipherText; // Bufor dla szyfrogramu
byte[] plainTextBytes = plainText.getBytes(); // Reprezentacja tekstu jawnego w bajtach
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec); //Inicjalizacja obiektu dla operacji szyfrowania z kluczem okreslonym przez keySpec:
cipherText = new byte[cipher.getOutputSize(plainTextBytes.length)]; //Utworzenie buforu dla szyfrogramu
cipherTextLength = cipher.update(plainTextBytes, 0, plainTextBytes.length, cipherText, 0); // Szyfrowanie tekstu jawnego
cipherTextLength += cipher.doFinal(cipherText, cipherTextLength); //Zakonczenie szyfrowania
return new BigInteger(1, cipherText).toString(16); // zapisanie 16
}
public String decryptText(String ciptherTextString) throws InvalidKeyException, InvalidAlgorithmParameterException, ShortBufferException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException{
byte[] cipherTextBytes = ciptherTextString.getBytes();
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); //Inicjalizacja obiektu cipher dla odszyfrowywania z kluczem okreslonym przez keySpec
byte[] plainTextBytes = new byte[cipher.getOutputSize(cipherTextBytes.length)]; // Utworzenie wyzerowanej tablicy
int plainTextLength = cipher.update(cipherTextBytes, 0, cipherTextBytes.length, plainTextBytes, 0);
plainTextLength += cipher.doFinal(plainTextBytes, plainTextLength);
return new String(plainTextBytes); //Odtworzona wiadomosc
}
}知道我该怎么做吗?
发布于 2013-01-03 23:04:43
你做的比必要的困难,而且你在加密你的密码文本
cipher.doFinal(cipherText, cipherTextLength);我要改写如下:
public String encryptText(String plainText) throws ... {
byte[] plainTextBytes = plainText.getBytes("UTF8");
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] encrypted = cipher.doFinal(plainTextBytes);
return toHex(encrypted);
}
public String decryptText(String cipherTextString) throws ... {
byte[] cipherTextBytes = fromHex(cipherTextString);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] plainTextBytes = cipher.doFinal(cipherTextBytes);
return new String(plainTextBytes, "UTF8");
}发布于 2013-01-03 22:52:51
据我所知,您正在从加密算法中获取字节数组输出,并使用BigInteger将其转换为十六进制字符串。然后,解密算法接受十六进制字符串,并使用.toString()将其转换为十六进制字符串中ASCII字符的字节表示形式。
这就是您的代码出错的地方(以及其他地方)。不是将十六进制字符串输出"FFFF“转换为字节数组[0xff, 0xff],而是将其转换为字节数组[0x46,0x46,0x46,0x46] (例如,大写F的ASCII字节表示)。这意味着不仅转换中的所有字节都会出错,字节数组的长度也会错误(这将导致您在问题中列出的异常)。
相反,您应该从加密方法返回byte[],并在解密方法中接受byte[]作为参数。否则,您应该使用类似Apache的十六进制类来可靠地在字节数组和十六进制字符串之间进行转换。
https://stackoverflow.com/questions/14124936
复制相似问题