Я пытаюсь реализовать алгоритм шифрования на основе пароля, но получаю следующее исключение:
javax.crypto.BadPaddingException: данный последний блок неправильно заполнен
В чем может быть проблема?
Вот мой код:
public class PasswordCrypter {
private Key key;
public PasswordCrypter(String password) {
try{
KeyGenerator generator;
generator = KeyGenerator.getInstance("DES");
SecureRandom sec = new SecureRandom(password.getBytes());
generator.init(sec);
key = generator.generateKey();
} catch (Exception e) {
e.printStackTrace();
}
}
public byte[] encrypt(byte[] array) throws CrypterException {
try{
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(array);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public byte[] decrypt(byte[] array) throws CrypterException{
try{
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key);
return cipher.doFinal(array);
} catch(Exception e ){
e.printStackTrace();
}
return null;
}
}
(Тест JUnit)
public class PasswordCrypterTest {
private static final byte[] MESSAGE = "Alpacas are awesome!".getBytes();
private PasswordCrypter[] passwordCrypters;
private byte[][] encryptedMessages;
@Before
public void setUp() {
passwordCrypters = new PasswordCrypter[] {
new PasswordCrypter("passwd"),
new PasswordCrypter("passwd"),
new PasswordCrypter("otherPasswd")
};
encryptedMessages = new byte[passwordCrypters.length][];
for (int i = 0; i < passwordCrypters.length; i++) {
encryptedMessages[i] = passwordCrypters[i].encrypt(MESSAGE);
}
}
@Test
public void testEncrypt() {
for (byte[] encryptedMessage : encryptedMessages) {
assertFalse(Arrays.equals(MESSAGE, encryptedMessage));
}
assertFalse(Arrays.equals(encryptedMessages[0], encryptedMessages[2]));
assertFalse(Arrays.equals(encryptedMessages[1], encryptedMessages[2]));
}
@Test
public void testDecrypt() {
for (int i = 0; i < passwordCrypters.length; i++) {
assertArrayEquals(MESSAGE, passwordCrypters[i].decrypt(encryptedMessages[i]));
}
assertArrayEquals(MESSAGE, passwordCrypters[0].decrypt(encryptedMessages[1]));
assertArrayEquals(MESSAGE, passwordCrypters[1].decrypt(encryptedMessages[0]));
try {
assertFalse(Arrays.equals(MESSAGE, passwordCrypters[0].decrypt(encryptedMessages[2])));
} catch (CrypterException e) {
// Anything goes as long as the above statement is not true.
}
try {
assertFalse(Arrays.equals(MESSAGE, passwordCrypters[2].decrypt(encryptedMessages[1])));
} catch (CrypterException e) {
// Anything goes as long as the above statement is not true.
}
}
}
javax.crypto.BadPaddingException: Given final block not properly padded
. Должен ли я рассматривать это как неправильный ключ?в зависимости от алгоритма криптографии, который вы используете, вам, возможно, придется добавить несколько байтов заполнения в конце перед шифрованием массива байтов, чтобы длина массива байтов была кратна размеру блока:
В частности, в вашем случае выбранная вами схема заполнения - это PKCS5, описанная здесь: http://www.rsa.com/products/bsafe/documentation/cryptoj35html/doc/dev_guide/group_ CJ _SYM__PAD.html
(Я предполагаю, что у вас проблема при попытке зашифровать)
Вы можете выбрать схему заполнения при создании экземпляра объекта Cipher. Поддерживаемые значения зависят от используемого вами провайдера безопасности.
Кстати, вы уверены, что хотите использовать симметричный механизм шифрования для шифрования паролей? Не было бы лучше одностороннего хеширования? Если вам действительно нужно расшифровать пароли, DES - довольно слабое решение, вам может быть интересно использовать что-то более сильное, например AES, если вам нужно придерживаться симметричного алгоритма.
источник
Я столкнулся с этой проблемой из-за операционной системы, простой для другой платформы реализации JRE.
будет иметь такое же значение в Windows, а в Linux - другое. Так что в Linux нужно поменять на
"SHA1PRNG" - это используемый алгоритм, вы можете найти здесь дополнительную информацию об алгоритмах.
источник
Это также может быть проблемой при вводе неправильного пароля для ключа подписи.
источник