Próbuję zaimplementować algorytm szyfrowania oparty na haśle, ale pojawia się ten wyjątek:
javax.crypto.BadPaddingException: podany końcowy blok nie jest odpowiednio wypełniony
Co może być problemem?
Oto mój kod:
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;
}
}
(Test 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
. Czy powinienem traktować to jako zły klucz?w zależności od używanego algorytmu kryptograficznego może być konieczne dodanie kilku bajtów wypełniających na końcu przed zaszyfrowaniem tablicy bajtów, aby długość tablicy bajtów była wielokrotnością rozmiaru bloku:
Konkretnie w Twoim przypadku wybrany schemat dopełnienia to PKCS5, który jest opisany tutaj: http://www.rsa.com/products/bsafe/documentation/cryptoj35html/doc/dev_guide/group_ CJ _SYM__PAD.html
(Zakładam, że masz problem podczas próby zaszyfrowania)
Możesz wybrać schemat dopełniania podczas tworzenia wystąpienia obiektu Cipher. Obsługiwane wartości zależą od używanego dostawcy zabezpieczeń.
A tak przy okazji, czy na pewno chcesz używać mechanizmu szyfrowania symetrycznego do szyfrowania haseł? Czy nie byłby lepszy hasz w jedną stronę? Jeśli naprawdę potrzebujesz możliwości odszyfrowania haseł, DES jest dość słabym rozwiązaniem, możesz być zainteresowany użyciem czegoś silniejszego, takiego jak AES, jeśli chcesz pozostać przy algorytmie symetrycznym.
źródło
Spotkałem się z tym problemem ze względu na system operacyjny, prostą na inną platformę o implementacji JRE.
otrzyma tę samą wartość w systemie Windows, podczas gdy jest inna w systemie Linux. Więc w Linuksie należy zmienić na
Użyty algorytm to „SHA1PRNG”. Więcej informacji na temat algorytmów można znaleźć tutaj .
źródło
Może to również stanowić problem, gdy wprowadzisz nieprawidłowe hasło do klucza podpisu.
źródło