下面的代码虽然有效,但是当我连续投掷“给定最后一块没有正确填充”时,有些时候也是如此。我觉得我在某处发生了一个小错误。 你能帮我解决一下这个问题吗?
异常堆栈:
Exception in thread "main" javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2086)
at MCrypt.decrypt(MCrypt.java:87)
at MCrypt.main(MCrypt.java:21)
我的代码:
import java.security.SecureRandom;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class MCrypt {
private int iterationCount = 10000;
private int saltLength = 8; // bytes; 64 bits
private int keyLength = 128;
public static void main(String[] args) throws Exception {
MCrypt mc = new MCrypt();
String encryptedData = mc.encrypt("1234");
MCrypt mc1 = new MCrypt();
System.out.println(new String(mc1.decrypt(new String(encryptedData),
"1234"), "UTF-8"));
}
public MCrypt() {
}
public String encrypt(String text) throws Exception {
if (text == null || text.length() == 0)
throw new Exception("Empty string");
byte[] encrypted = null;
SecureRandom random = new SecureRandom();
byte[] salt = new byte[saltLength];
random.nextBytes(salt);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = new byte[cipher.getBlockSize()];
random.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);
KeySpec keySpec = new PBEKeySpec(text.toCharArray(), salt,
iterationCount, keyLength);
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
SecretKey key = new SecretKeySpec(keyBytes, "AES");
cipher.init(Cipher.ENCRYPT_MODE, key, ivParams);
encrypted = cipher.doFinal(text.getBytes("UTF-8"));
String encryptedStr = Base64.encodeBytes(encrypted);
StringBuffer strBuf = new StringBuffer();
strBuf.append(new String(encryptedStr));
strBuf.append("]");
strBuf.append(new String(salt));
strBuf.append("]");
strBuf.append(new String(iv));
return new String(Base64.encodeBytes(strBuf.toString().getBytes()));
}
public byte[] decrypt(String code, String pwd) throws Exception {
if (code == null || code.length() == 0)
throw new Exception("Empty string");
String[] fields = new String(Base64.decode(code)).split("]");
byte[] cipherBytes = Base64.decode(fields[0]);
byte[] salt = fields[1].getBytes();
byte[] iv = fields[2].getBytes();
KeySpec keySpec = new PBEKeySpec(pwd.toCharArray(), salt,
iterationCount, keyLength);
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
byte[] keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
SecretKey key = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
IvParameterSpec ivParams = new IvParameterSpec(iv);
byte[] decrypted = null;
cipher.init(Cipher.DECRYPT_MODE, key, ivParams);
decrypted = cipher.doFinal(cipherBytes);
return decrypted;
}
}
答案 0 :(得分:0)
请看这个
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import android.util.Base64;
import android.util.Log;
public class AesFileIo {
// private static final String AES_ALGORITHM = "AES/CTR/NoPadding";
private static final String AES_ALGORITHM = "AES/CBC/PKCS5Padding";
private SecretKeySpec secretKeySpec;
private IvParameterSpec ivSpec;
public AesFileIo(byte[] aesKey, byte[] iv) {
ivSpec = new IvParameterSpec(iv);
secretKeySpec = new SecretKeySpec(aesKey, "AES");
}
public String decrypt(String text) {
StringBuilder stringBuilder = new StringBuilder();
try {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivSpec);
byte[] decordedValue = Base64.decode(text,Base64.DEFAULT);
String decryptedValue = new String(cipher.doFinal(decordedValue),"UTF-8");
Log.e("decrypted Value :",decryptedValue);
return decryptedValue;
} catch (Exception e) {
Log.e(this.getClass().toString(), e.getMessage(), e);
}
return stringBuilder.toString();
}
public String encrypt(String text) {
String encryptedValue=null;
try {
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
byte[] encValue = cipher.doFinal(text.getBytes());
encryptedValue = Base64.encodeToString(encValue,Base64.DEFAULT);
} catch (Exception e) {
Log.e(this.getClass().toString(), e.getMessage(), e);
}
return encryptedValue;
}
}
如何使用
public static byte[] iv = { '0', '0','0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0' };
private static final byte[] keyValue = new byte[] { 'b', 'i', 'r', 'a', 'j', 'z', 'a', 'l', 'a', 'v', 'a', 'd', 'i', 'y', 'a', 'r' };
AesFileIo aes = new AesFileIo(keyValue, iv);
String encrypetedText = aes.encrypt(str);
String decryptedText = aes.decrypt(encrypetedText);
System.out.println("EncrypetedText : " + encrypetedText);
System.out.println("DecryptedText : " + decryptedText);