Шифрование Java AES – как исправить IllegalBlockSizeExceptionJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Шифрование Java AES – как исправить IllegalBlockSizeException

Сообщение Anonymous »

У меня есть два метода Java: один для шифрования, другой для расшифровки. Я хотел бы зашифровать/расшифровать пароль с помощью мастер-пароля. Но когда я пытаюсь расшифровать зашифрованный пароль, я получаю сообщение. Причина: javax.crypto.IllegalBlockSizeException: длина ввода должна быть кратна 16 при расшифровке с помощью дополненного шифра. Я не могу понять, почему я это понимаю. Я мог бы предположить, что это как-то связано с преобразованием строки в байт, но я не уверен. Как это исправить?
Код:

Код: Выделить всё

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
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 AESEncryption implements EncryptionModuleInterface {
private static final int ITERATION_COUNT = 1000000;
private static final int KEY_LENGTH = 256;
private static final String PBKDF_ALGORITHM = "PBKDF2WithHmacSHA1";
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
private static final String ALGORITHM = "AES";

@Override
public String encryptPassword(String password, String masterpassword) {
byte[] finalCiphertext;

SecureRandom random = new SecureRandom();
byte[] salt = new byte[16];
random.nextBytes(salt);

KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH);

try {
SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF_ALGORITHM);
byte[] key = factory.generateSecret(spec).getEncoded();
SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);

byte[] ivBytes = new byte[16];
random.nextBytes(ivBytes);
IvParameterSpec iv = new IvParameterSpec(ivBytes);

Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);

byte[] inputBytes = password.getBytes();

byte[] encValue = cipher.doFinal(inputBytes);
finalCiphertext = new byte[encValue.length+2*16];
System.arraycopy(ivBytes, 0, finalCiphertext, 0, 16);
System.arraycopy(salt, 0, finalCiphertext, 16, 16);
System.arraycopy(encValue, 0, finalCiphertext, 32, encValue.length);

} catch (NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException |
InvalidKeySpecException | NoSuchAlgorithmException | IllegalBlockSizeException | BadPaddingException e) {
throw new RuntimeException(e);
}

return new String(finalCiphertext, StandardCharsets.UTF_8);
}

@Override
public String decryptPassword(String password, String masterpassword) {
byte[] ivBytes = new byte[16];
byte[] salt = new byte[16];
byte[] encValue;

byte[] readEncryptedBytesWithIvAndSaltPrefix = password.getBytes();
byte[] inputBytes = new byte[readEncryptedBytesWithIvAndSaltPrefix.length - 32];

System.arraycopy(readEncryptedBytesWithIvAndSaltPrefix, 0, ivBytes, 0, 16);
System.arraycopy(readEncryptedBytesWithIvAndSaltPrefix, 16, salt, 0, 16);
System.arraycopy(readEncryptedBytesWithIvAndSaltPrefix, 32, inputBytes, 0, readEncryptedBytesWithIvAndSaltPrefix.length - 32);

KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, ITERATION_COUNT, KEY_LENGTH);

try {
SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF_ALGORITHM);
byte[] key = factory.generateSecret(spec).getEncoded();
SecretKeySpec keySpec = new SecretKeySpec(key, ALGORITHM);

IvParameterSpec iv = new IvParameterSpec(ivBytes);

Cipher cipher = Cipher.getInstance(TRANSFORMATION);
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);

encValue = cipher.doFinal(inputBytes);

} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException |
BadPaddingException | InvalidKeySpecException | InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
}

return new String(encValue, StandardCharsets.UTF_8);
}
}
Изменить:
Я могу преобразовать двоичный массив байтов в шестнадцатеричную строку:

Код: Выделить всё

StringBuilder result = new StringBuilder();
for (byte b : finalCiphertext){
result.append(String.format("%02X", b));
}

return result.toString();
< /code>
Но у меня есть проблемы, чтобы преобразовать шестнадцатеричную строку обратно в двоичный байтовый массив.  < /p>
StringBuilder stringBuilder = new StringBuilder();
HashMap hashMap = new HashMap();
hashMap.put('0', "0000");
hashMap.put('1', "0001");
hashMap.put('2', "0010");
hashMap.put('3', "0011");
hashMap.put('4', "0100");
hashMap.put('5', "0101");
hashMap.put('6', "0110");
hashMap.put('7', "0111");
hashMap.put('8', "1000");
hashMap.put('9', "1001");
hashMap.put('A', "1010");
hashMap.put('B', "1011");
hashMap.put('C', "1100");
hashMap.put('D', "1101");
hashMap.put('E', "1110");
hashMap.put('F', "1111");

for (int i = 0; i < password.length(); i++) {
stringBuilder.append(hashMap.get(password.charAt(i)));
}

String binaryString = stringBuilder.toString();
byte[] readEncryptedBytesWithIvAndSaltPrefix = binaryString.getBytes();
System.out.println(Arrays.toString(readEncryptedBytesWithIvAndSaltPrefix));
Последний оператор печати возвращает массив с числами 48 и 49.
С этими дополнениями я получаю «Вызвано: javax.crypto.BadPaddingException: Данный последний блок не дополнен должным образом. Такие проблемы могут возникнуть, если при расшифровке используется неверный ключ.

Подробнее здесь: https://stackoverflow.com/questions/793 ... eexception
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»