Java 试图解密字符串的IllegalBlockSizeException
我在JRE 1.6上使用AES 128位加密 我一直在尝试解密encrypt()生成的字符串时遇到此异常: 我注意到加密字符串有24字节长,wtf?例如,“fb/8asoHS/ShyCDV46t/Aw=” 它们不应该是16字节吗?无论如何,我不确定这是否是问题所在 资料来源如下:Java 试图解密字符串的IllegalBlockSizeException,java,encryption,cryptography,jce,Java,Encryption,Cryptography,Jce,我在JRE 1.6上使用AES 128位加密 我一直在尝试解密encrypt()生成的字符串时遇到此异常: 我注意到加密字符串有24字节长,wtf?例如,“fb/8asoHS/ShyCDV46t/Aw=” 它们不应该是16字节吗?无论如何,我不确定这是否是问题所在 资料来源如下: package com.axa.oe.mongo; import java.security.spec.InvalidKeySpecException; import java.security.InvalidAlg
package com.axa.oe.mongo;
import java.security.spec.InvalidKeySpecException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import com.ibm.broker.javacompute.Base64;
public class Security {
private static final String AES_KEY = "blah";
private SecretKeySpec keyObj;
private Cipher cipher;
private IvParameterSpec ivObj;
public Security() throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException {
// A constant IV
byte[] iv = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
this.ivObj = new IvParameterSpec(iv);
byte[] key = AES_KEY.getBytes();
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
this.keyObj = new SecretKeySpec(key, "AES");
// Create a Cipher by specifying the following parameters
// a. Algorithm name - here it is AES
// b. Mode - here it is CBC mode
// c. Padding - e.g. PKCS7 or PKCS5
this.cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
}
public String encrypt(String strDataToEncrypt) throws InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException {
String strCipherText = new String();
this.cipher.init(Cipher.ENCRYPT_MODE, this.keyObj, this.ivObj);
// Encrypt the Data
// a. Declare / Initialize the Data. Here the data is of type String
// b. Convert the Input Text to Bytes
// c. Encrypt the bytes using doFinal method
byte[] byteDataToEncrypt = strDataToEncrypt.getBytes();
byte[] byteCipherText = this.cipher.doFinal(byteDataToEncrypt);
// b64 is done differently on Android
strCipherText = Base64.encode(byteCipherText);
return strCipherText;
}
public String decrypt(String strCipherText) throws InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException {
String strDecryptedText = new String();
// Initialize the Cipher for Encryption
this.cipher.init(Cipher.DECRYPT_MODE, this.keyObj, this.ivObj);
// Decrypt the Data
// a. Initialize a new instance of Cipher for Decryption (normally don't reuse the same object)
// Be sure to obtain the same IV bytes for CBC mode.
// b. Decrypt the cipher bytes using doFinal method
byte[] byteDecryptedText = this.cipher.doFinal(strCipherText.getBytes());
strDecryptedText = new String(byteDecryptedText);
return strDecryptedText;
}
}
我使用全局密钥是因为应用程序不使用会话或登录。还要注意IV是一个常量字节数组。我的JCE版本有点过时了,我正在尝试升级它,但目前陷入了官僚主义的泥潭,所以我必须做出适当的
非常感谢您的帮助 看起来像
fb/8asoHS/ShyCDV46t/Aw==
的字符串是密码文本字节数组的编码表示形式
密钥开始时有16个字节长。Base64编码将长度增加到4/3,因为它使用更少的字符来表示字节。16 * 4/3 = 22. 但是Base64一次需要转换3个字节,因此它将字节填充为3的倍数,因此16->18*4/3=24。末尾的等号是Base64中这种填充的典型产物
加密后,您将对密码文本进行Base64编码。在解密之前,您需要对密码文本进行Base64解码
可能是这样的:
public String decrypt(String strCipherText) throws InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException {
String strDecryptedText = new String();
// Initialize the Cipher for Encryption
this.cipher.init(Cipher.DECRYPT_MODE, this.keyObj, this.ivObj);
// Decode the Base64 text
byte[] cipherBytes = Base64.decode(strCipherText);
// Decrypt the Data
// a. Initialize a new instance of Cipher for Decryption (normally don't reuse the same object)
// Be sure to obtain the same IV bytes for CBC mode.
// b. Decrypt the cipher bytes using doFinal method
byte[] byteDecryptedText = this.cipher.doFinal(cipherBytes);
strDecryptedText = new String(byteDecryptedText);
return strDecryptedText;
}
我想是这样的,谢谢!我在上使用了这个示例,但出于某种原因,他们没有在其中使用Base64解码。
public String decrypt(String strCipherText) throws InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, NoSuchPaddingException {
String strDecryptedText = new String();
// Initialize the Cipher for Encryption
this.cipher.init(Cipher.DECRYPT_MODE, this.keyObj, this.ivObj);
// Decode the Base64 text
byte[] cipherBytes = Base64.decode(strCipherText);
// Decrypt the Data
// a. Initialize a new instance of Cipher for Decryption (normally don't reuse the same object)
// Be sure to obtain the same IV bytes for CBC mode.
// b. Decrypt the cipher bytes using doFinal method
byte[] byteDecryptedText = this.cipher.doFinal(cipherBytes);
strDecryptedText = new String(byteDecryptedText);
return strDecryptedText;
}