Java 错误:给定的最后一个块没有正确填充。如果在解密过程中使用了坏密钥,则会出现此类问题
在使用Java加密技术时,我面临以下问题 错误Decjavax.crypto.BadPaddingException:给定的最终块不是 垫得很好。如果在操作过程中使用了错误的密钥,则可能会出现此类问题 解密 我检查了所有可能的答案,但找不到这背后的确切原因 一个观察结果是,当我使用AES/CBC/NoPadding代替AES/CBC/PKCS5Padding时,我可以成功地执行它。 这是我的代码片段Java 错误:给定的最后一个块没有正确填充。如果在解密过程中使用了坏密钥,则会出现此类问题,java,encryption,cryptography,aes,padding,Java,Encryption,Cryptography,Aes,Padding,在使用Java加密技术时,我面临以下问题 错误Decjavax.crypto.BadPaddingException:给定的最终块不是 垫得很好。如果在操作过程中使用了错误的密钥,则可能会出现此类问题 解密 我检查了所有可能的答案,但找不到这背后的确切原因 一个观察结果是,当我使用AES/CBC/NoPadding代替AES/CBC/PKCS5Padding时,我可以成功地执行它。 这是我的代码片段 package demo; import javax.crypto.Cipher; impor
package demo;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
public class TestEncryption {
private static final int BUFFER_SIZE = 32;
private static final int KEY_ITERATIONS = 65535;
private static final int DEFAULT_KEY_BITS = 128;
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static final String TRANSFORMATION = "AES";
private static final String PBKDF_2_WITH_HMAC_SHA_256 = "PBKDF2WithHmacSHA256";
private static final int IV_SIZE = 16;
private final Cipher ecipher;
private final Cipher dcipher;
private SecretKey secretKey;
/**
* Initialize the ciphers using the given key.
* @param key
* @param keyBits
*/
public TestEncryption(String key, int keyBits) {
byte[] salt = new byte[8];
if (key.length() < 8) {
throw new IllegalArgumentException("key must contain 8 characters or more");
}
for (int i = 0; i < 8; i = i + 1) {
salt[i] = ((byte) key.charAt(i));
}
char[] password = key.toCharArray();
int keyLength = DEFAULT_KEY_BITS;
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF_2_WITH_HMAC_SHA_256);
if (keyBits == 256) {
keyLength = 256;
}
KeySpec spec = new PBEKeySpec(password, salt, KEY_ITERATIONS, keyLength);
secretKey = new SecretKeySpec(factory.generateSecret(spec).getEncoded(), TRANSFORMATION);
ecipher = Cipher.getInstance(ALGORITHM);
dcipher = Cipher.getInstance(ALGORITHM);
} catch (InvalidKeySpecException | NoSuchPaddingException | NoSuchAlgorithmException e) {
throw new RuntimeException("Failed to initialize encryption.", e);
}
}
public void encryptFile(File src, File dest){
try {
InputStream inputStream = new FileInputStream(src);
OutputStream outputStream = new FileOutputStream(dest);
CipherOutputStream cipherOutputStream= new CipherOutputStream(outputStream, ecipher);
// Generating IV.
byte[] iv = new byte[IV_SIZE];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// First write the IV at the beginning of the encrypted file.
outputStream.write(iv, 0, IV_SIZE);
System.out.println("key " + secretKey);
// Initialize cipher with IV
ecipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
// Encrypt input file and write in to output
while ((bytesRead = inputStream.read(buffer)) > 0) {
cipherOutputStream.write(buffer, 0, bytesRead);
}
} catch (InvalidKeyException | InvalidAlgorithmParameterException | IOException e) {
System.out.println("error encryption" + e.getMessage());
e.printStackTrace();
}
}
public void decryptFile(File srcFile, File destFile) {
try (
InputStream is = new FileInputStream(srcFile);
OutputStream out = new FileOutputStream(destFile);
CipherInputStream cis = new CipherInputStream(is, dcipher)
) {
// Extract IV
byte[] iv = new byte[IV_SIZE];
is.read(iv, 0, IV_SIZE);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Initialize cypher with IV
dcipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = cis.read(buffer)) > 0) {
out.write(buffer, 0, bytesRead);
}
} catch ( InvalidKeyException | InvalidAlgorithmParameterException | IOException e) {
System.out.println("error decr" + e.getMessage());
e.printStackTrace();
}
}
}
package demo;
import java.io.*;
public class Client {
public static void main(String [] args){
File tempFile =null, src = null, dest = null;
try {
tempFile = new File("temp.txt");
src = new File("C:\\Users\\x\\Desktop\\test.txt");
dest = new File("C:\\Users\\x\\Desktop\\out.txt");
TestEncryption encryption = new TestEncryption("helloworld", 256);
encryption.encryptFile(src, tempFile);
encryption.decryptFile(tempFile, dest);
}
finally {
tempFile.delete();
//src.delete();
//dest.delete();
}
}
}
软件包演示;
导入javax.crypto.Cipher;
导入javax.crypto.cipheriputstream;
导入javax.crypto.CipherOutputStream;
导入javax.crypto.NoSuchPaddingException;
导入javax.crypto.SecretKey;
导入javax.crypto.SecretKeyFactory;
导入javax.crypto.spec.IvParameterSpec;
导入javax.crypto.spec.PBEKeySpec;
导入javax.crypto.spec.SecretKeySpec;
导入java.io.File;
导入java.io.FileInputStream;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.security.invalidalgorithParameterException;
导入java.security.InvalidKeyException;
导入java.security.NoSuchAlgorithmException;
导入java.security.SecureRandom;
导入java.security.spec.InvalidKeySpecException;
导入java.security.spec.KeySpec;
公共类测试加密{
私有静态最终整数缓冲区大小=32;
私有静态最终整数密钥迭代次数=65535;
私有静态最终整数默认值\密钥\位=128;
私有静态最终字符串算法=“AES/CBC/PKCS5Padding”;
私有静态最终字符串转换=“AES”;
私有静态最终字符串PBKDF_2_WITH_HMAC_SHA_256=“PBKDF2WithHmacSHA256”;
专用静态最终int IV_尺寸=16;
专用最终密码译码器;
专用最终密码dcipher;
私密密钥;
/**
*使用给定的密钥初始化密码。
*@param-key
*@param密钥位
*/
公共测试加密(字符串键、int键位){
字节[]salt=新字节[8];
if(key.length()<8){
抛出新的IllegalArgumentException(“密钥必须包含8个或更多字符”);
}
对于(int i=0;i<8;i=i+1){
salt[i]=((字节)key.charAt(i));
}
char[]password=key.toCharArray();
int keyLength=默认密钥位;
试一试{
SecretKeyFactory factory=SecretKeyFactory.getInstance(PBKDF_2_和_HMAC_SHA_256);
如果(关键位==256){
keyLength=256;
}
KeySpec spec=新的PBEKeySpec(密码、salt、密钥迭代次数、密钥长度);
secretKey=newsecretkeyspec(factory.generateSecret(spec.getEncoded(),转换);
ecipher=Cipher.getInstance(算法);
dcipher=Cipher.getInstance(算法);
}捕获(InvalidKeySpecException | NoSuchPaddingException | NoSuchAlgorithme异常){
抛出新的运行时异常(“未能初始化加密。”,e);
}
}
公共无效加密文件(文件src、文件dest){
试一试{
InputStream InputStream=新文件InputStream(src);
OutputStream OutputStream=新文件OutputStream(dest);
CipherOutputStream CipherOutputStream=新的CipherOutputStream(outputStream,ecipher);
//生成IV。
字节[]iv=新字节[iv_大小];
SecureRandom=新的SecureRandom();
随机。下一字节(iv);
IvParameterSpec IvParameterSpec=新的IvParameterSpec(iv);
//首先在加密文件的开头写入IV。
outputStream.write(iv,0,iv_大小);
System.out.println(“键”+secretKey);
//用IV初始化密码
ecipher.init(Cipher.ENCRYPT_模式,secretKey,ivParameterSpec);
字节[]缓冲区=新字节[缓冲区大小];
int字节读取;
//加密输入文件并写入输出
而((bytesRead=inputStream.read(buffer))>0){
cipherOutputStream.write(缓冲区,0,字节读取);
}
}捕获(InvalidKeyException | InvalidAlgorithmParameterException | IOException){
System.out.println(“错误加密”+e.getMessage());
e、 printStackTrace();
}
}
公共无效解密文件(文件srcFile、文件destFile){
试一试(
InputStream is=新文件InputStream(srcFile);
OutputStream out=新文件OutputStream(destFile);
CipherInputStream cis=新的CipherInputStream(is,dcipher)
) {
//摘录四
字节[]iv=新字节[iv_大小];
读取(iv,0,iv_大小);
IvParameterSpec IvParameterSpec=新的IvParameterSpec(iv);
//用IV初始化cypher
dcipher.init(Cipher.DECRYPT_模式,secretKey,ivParameterSpec);
字节[]缓冲区=新字节[缓冲区大小];
int字节读取;
而((bytesRead=cis.read(buffer))>0){
out.write(缓冲区,0,字节读取);
}
}捕获(InvalidKeyException | InvalidAlgorithmParameterException | IOException){
System.out.println(“error decr”+e.getMessage());
e、 printStackTrace();
}
}
}
包装演示;
导入java.io.*;
公共类客户端{
公共静态void main(字符串[]args){
文件tempFile=null,src=null,dest=null;
试一试{
tempFile=新文件(“temp.txt”);
src=新文件(“C:\\Users\\x\\Desktop\\test.txt”);
dest=新文件(“C:\\Users\\x\\Desktop\\out.txt”);
TestEncryption encryption=新的TestEncryption(“helloworld”,256);
encryption.encryptFile(src,tempFile);
加密.解密文件(tempFile,dest);
}
最后{
public void encryptFile(File src, File dest) {
try (InputStream inputStream = new FileInputStream(src);
OutputStream outputStream = new FileOutputStream(dest)) {
try (CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, ecipher)) {
// Generating IV.
byte[] iv = new byte[IV_SIZE];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// First write the IV at the beginning of the encrypted file.
outputStream.write(iv, 0, IV_SIZE);
System.out.println("key 0x" + new BigInteger(1, secretKey.getEncoded()).toString(16));
// Initialize cipher with IV
ecipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
// Encrypt input file and write in to output
while ((bytesRead = inputStream.read(buffer)) >= 0) {
cipherOutputStream.write(buffer, 0, bytesRead);
}
}
} catch (InvalidKeyException | InvalidAlgorithmParameterException | IOException e) {
System.out.println("error encryption" + e.getMessage());
e.printStackTrace();
}
}
public void decryptFile(File srcFile, File destFile) {
try (InputStream is = new FileInputStream(srcFile); OutputStream out = new FileOutputStream(destFile)) {
try (CipherInputStream cis = new CipherInputStream(is, dcipher)) {
// Extract IV
byte[] iv = is.readNBytes(IV_SIZE);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Initialize cypher with IV
dcipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
byte[] buffer = new byte[BUFFER_SIZE];
int bytesRead;
while ((bytesRead = cis.read(buffer)) >= 0) {
out.write(buffer, 0, bytesRead);
}
}
} catch (InvalidKeyException | InvalidAlgorithmParameterException | IOException e) {
System.out.println("error decr" + e.getMessage());
e.printStackTrace();
}
}