Ich versuche, einen kennwortbasierten Verschlüsselungsalgorithmus zu implementieren, erhalte jedoch die folgende Ausnahme:
javax.crypto.BadPaddingException: Der letzte Block ist nicht richtig aufgefüllt
Was könnte das Problem sein?
Hier ist mein Code:
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;
}
}
(Der JUnit-Test)
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
. Sollte ich dies als falschen Schlüssel behandeln?Abhängig von dem von Ihnen verwendeten Kryptografiealgorithmus müssen Sie möglicherweise am Ende einige Auffüllbytes hinzufügen, bevor Sie ein Bytearray verschlüsseln, damit die Länge des Bytearrays ein Vielfaches der Blockgröße beträgt:
Speziell in Ihrem Fall ist das von Ihnen gewählte Auffüllschema PKCS5, das hier beschrieben wird: http://www.rsa.com/products/bsafe/documentation/cryptoj35html/doc/dev_guide/group_ CJ _SYM__PAD.html
(Ich gehe davon aus, dass Sie das Problem haben, wenn Sie versuchen zu verschlüsseln)
Sie können Ihr Auffüllschema auswählen, wenn Sie das Cipher-Objekt instanziieren. Unterstützte Werte hängen vom verwendeten Sicherheitsanbieter ab.
Sind Sie übrigens sicher, dass Sie einen symmetrischen Verschlüsselungsmechanismus zum Verschlüsseln von Passwörtern verwenden möchten? Wäre ein Einweg-Hash nicht besser? Wenn Sie wirklich in der Lage sein müssen, Passwörter zu entschlüsseln, ist DES eine ziemlich schwache Lösung. Sie könnten daran interessiert sein, etwas Stärkeres wie AES zu verwenden, wenn Sie bei einem symmetrischen Algorithmus bleiben müssen.
quelle
Ich bin auf dieses Problem aufgrund des Betriebssystems gestoßen, das einfach zu einer anderen Plattform für die JRE-Implementierung gehört.
wird unter Windows den gleichen Wert erhalten, während es unter Linux anders ist. Also muss unter Linux auf geändert werden
„SHA1PRNG“ ist der Algorithmus verwendet, Sie verweisen hier für weitere Informationen über Algorithmen.
quelle
Dies kann auch ein Problem sein, wenn Sie ein falsches Passwort für Ihren Zeichenschlüssel eingeben.
quelle