gpt4 book ai didi

java - 解密 AES/CBC/PKCS5Padding 错误 : Given final block not properly padded

转载 作者:行者123 更新时间:2023-12-02 03:15:15 29 4
gpt4 key购买 nike

在大型加密文件上解密 AES/CBC/PKCS5Padding 密码时,我收到给出的最终 block 未正确填充错误。

我认为这个问题是由于在 cipher.init() 方法中添加错误的初始化 vector 引起的。

我无法在运行时读取整个文件,因此我需要加密固定大小的 block 。此时,我正在创建 IV 并将其存储到 .txt 文件中。但在解密方法中,我在每个解密周期都使用相同的 IV。我应该如何改变这个?

加密:

void encrypt() throws Exception{
char[] password = passwordText.getText().toCharArray();
byte[] salt = new byte[8];

/* Creating and saving salt */
salt = saveSalt(salt);

/* Securing password */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 128);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

if (choosedFile != null) {
/* Choosing algorithm for decryption */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

/* Getting plain file */
CipherInputStream fis = new CipherInputStream(new FileInputStream(choosedFile), cipher);
CipherOutputStream fos = new CipherOutputStream(new FileOutputStream(choosedFile+".encrypted"), cipher);

/* Encrypting and Measuring */
long startTime = System.currentTimeMillis();
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] rawText = new byte[128];
int count;
while((count = fis.read(rawText)) > 0) {
System.out.println(count);
byte[] encryptedText = cipher.doFinal(rawText);
fos.write(encryptedText, 0, count);
}
long stopTime = System.currentTimeMillis();

fis.close();
fos.close();

/* Creating initialization vector and storing*/
byte[] iVector = cipher.getIV();
saveIVector(iVector);

text.setText(text.getText() + "File was encrypted in " + (stopTime - startTime) + "ms.\n");
}

}

解密:

    void decrypt() throws Exception {
/* Getting salt */
byte[] salt = getSalt();
/* Getting initialization vector */
byte[] iVector = getIVector();
/* Getting user password */
char[] password = passwordText.getText().toCharArray();


/* Securing password */
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(password, salt, 65536, 128);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

if (choosedFile != null) {

/* Choosing algorithm for decryption */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
/* Getting ciphered file */


CipherInputStream fis = new CipherInputStream(new FileInputStream(choosedFile), cipher);
CipherOutputStream fos = new CipherOutputStream(new FileOutputStream(choosedFile+".decrypted"), cipher);

/* Decrypting and Measuring */
long startTime = System.currentTimeMillis();
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iVector));
byte[] rawText = new byte[128];
int count;
while((count = fis.read(rawText)) > 0) {
byte[] encryptedText = cipher.doFinal(rawText);
fos.write(encryptedText, 0, count);
}

long stopTime = System.currentTimeMillis();

fis.close();
fos.close();

最佳答案

使用CipherInputStreamCipherOutputStream时,流处理对密码的所有调用(这就是您在初始化时将密码传递给它的原因)。您只需正确初始化它,并通过流传输数据,密码流将对 update()doFinal() 进行所需的调用。请记住关闭 Steam 以触发 doFinal()

目前,您的代码以不受控制的方式多次通过密码传递数据,并且数据困惑。

此外,您只需要一个 CipherInputStream 进行解密,以及一个 CipherOutputStream 进行加密。在您当前的代码中,您同时使用加密和解密。

加密可能是这样的(这不处理 iv ..):

...     
cipher.init(Cipher.ENCRYPT_MODE, secret);
InputStream is = new FileInputStream(choosedFile);
OutputStream os = new CipherOutputStream(new FileOutputStream(choosedFile+".encrypted"), cipher);

byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
os.write(buffer, 0, len);
}

is.close();
os.close();
...

关于java - 解密 AES/CBC/PKCS5Padding 错误 : Given final block not properly padded,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40411116/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com