需要修复错误-javax.crypto.BadPaddingException:给定的最后一个块没有正确填充



我不确定我做错了什么。简而言之,我想用给定的secretKey并使用iv解密一个文件,我使用以下代码来解密:

package com.Crypt.test;
import javax.crypto.Cipher;
import javax.crypto.Mac;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.SecureRandom;
public class AES256CBCTest {
static String encoding = "UTF-8";
public static void main(String[] args) throws Exception {
String key = "BURP6070";
File inputFile = new File("/Users/jaynigam/Documents/workspace/EncryptDecrypt/files/test.xml.enc");
try {
BufferedReader br = new BufferedReader(new FileReader(inputFile));
String st;
File outputFile =null;
FileOutputStream outputStream = null;
try {
while ((st = br.readLine()) != null){
//decrypt(someString.getBytes(encoding), key);
String decrypted = decrypt(st.getBytes(), key);
outputFile = new File("/Users/jaynigam/Documents/workspace/EncryptDecrypt/files/decryptTest.xml.dec");
outputStream = new FileOutputStream(outputFile);
byte[] strToBytes = decrypted.getBytes(encoding);
outputStream.write(strToBytes);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
outputStream.close();
br.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//byte[] encrypted = encrypt(clean, key);

public static byte[] encrypt(String plainText, String key) throws Exception {
byte[] clean = plainText.getBytes();
// Generating IV.
int ivSize = 16;
byte[] iv = new byte[ivSize];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Hashing key.
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.update(key.getBytes());
byte[] keyBytes = new byte[32];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
// Encrypt.
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(clean);
// Combine IV and encrypted part.
byte[] encryptedIVAndText = new byte[ivSize + encrypted.length];
System.arraycopy(iv, 0, encryptedIVAndText, 0, ivSize);
System.arraycopy(encrypted, 0, encryptedIVAndText, ivSize, encrypted.length);
return encryptedIVAndText;
}
public static String decrypt(byte[] encryptedIvTextBytes, String key) throws Exception {
int ivSize = 16;
int keySize = 16;
// Extract IV.
byte[] iv = new byte[ivSize];
System.arraycopy(encryptedIvTextBytes, 0, iv, 0, iv.length);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Extract encrypted part.
int encryptedSize = encryptedIvTextBytes.length - ivSize;
byte[] encryptedBytes = new byte[encryptedSize];
System.arraycopy(encryptedIvTextBytes, ivSize, encryptedBytes, 0, encryptedSize);
// Hash key.
byte[] keyBytes = new byte[keySize];
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(key.getBytes());
System.arraycopy(md.digest(), 0, keyBytes, 0, keyBytes.length);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
// Decrypt.
Cipher cipherDecrypt = Cipher.getInstance("AES/CBC/NoPadding");
cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decrypted = cipherDecrypt.doFinal(encryptedBytes);
return new String(decrypted);
}
}

这将返回一个类似?lm:@?ڤ?w?)P@??s????Ka???0??{???w|k???o??的输出。我已经尝试过UTF-8解码。但是直到现在仍然没有运气。有人知道这件事的线索吗?

我遇到了和您完全相同的问题,也使用了相同的源代码!我在使用返回和输入参数byte[]时遇到了问题,所以我用Base64编码将其转换为String,所以我最终没有遇到编码问题。

我的班级:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.SecureRandom;
import java.util.Base64;

public class PasswordManager {
private static final Logger LOGGER = LoggerFactory.getLogger(PasswordManager.class);
private static final String key = "DdFfGg998012jffW"; // 128 bit key
private PasswordManager() {
}
public static String encrypt(String plainText) {
if (plainText == null) {
return null;
}
byte[] clean = plainText.getBytes();
// Generating IV.
int ivSize = 16;
byte[] iv = new byte[ivSize];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
try {
// Hashing key.
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(key.getBytes(StandardCharsets.UTF_8));
byte[] keyBytes = new byte[16];
System.arraycopy(digest.digest(), 0, keyBytes, 0, keyBytes.length);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
// Encrypt.
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encrypted = cipher.doFinal(clean);
// Combine IV and encrypted part.
byte[] encryptedIVAndText = new byte[ivSize + encrypted.length];
System.arraycopy(iv, 0, encryptedIVAndText, 0, ivSize);
System.arraycopy(encrypted, 0, encryptedIVAndText, ivSize, encrypted.length);
return Base64.getEncoder().encodeToString(encryptedIVAndText);
} catch (Exception e) {
LOGGER.error("Exception in decrypting a password. Returning null", e);
return null;
}
}
public static String decrypt(String encryptedString) {
if (encryptedString == null) {
return null;
}
byte[] encryptedIvTextBytes = Base64.getDecoder().decode(encryptedString);
int ivSize = 16;
int keySize = 16;
// Extract IV.
byte[] iv = new byte[ivSize];
System.arraycopy(encryptedIvTextBytes, 0, iv, 0, iv.length);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Extract encrypted part.
int encryptedSize = encryptedIvTextBytes.length - ivSize;
byte[] encryptedBytes = new byte[encryptedSize];
System.arraycopy(encryptedIvTextBytes, ivSize, encryptedBytes, 0, encryptedSize);
try {
// Hash key.
byte[] keyBytes = new byte[keySize];
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(key.getBytes());
System.arraycopy(md.digest(), 0, keyBytes, 0, keyBytes.length);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
// Decrypt.
Cipher cipherDecrypt = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] decrypted = cipherDecrypt.doFinal(encryptedBytes);
return new String(decrypted);
} catch (Exception e) {
LOGGER.error("Exception in decrypting a password. Returning null", e);
return null;
}
}
}

也试着用一把和我的一样长的钥匙,先试一下,因为这可能是个问题。在while循环中尝试对字符串操作使用Base64之后。

希望它能帮助你。

最新更新