javax.crypto.IllegalBlockSizeException: Eingabe der Länge kein Vielfaches von 16 bytes
Habe ich eine ArrayList, die Objekte enthält. Objekt ist ein container für login/pass.
Ich versuche zu Dekodieren, weil ich zu serialisieren, die in der lokalen Datei für die Erholung nach der anderen starten.
Problem ist während der Verschlüsselung, die ich erhalten
javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1039)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:983)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:845)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
Und ich komplett nicht verstehe, warum. Meiner Meinung nach Base64 sollten den Umgang mit diesem. Aber vielleicht verstehe ich nicht richtig seine Bedeutung.
Ich benutze zum verschlüsseln/deccode
public class Move
{
private static Move instance;
String key = "pT5IkWNR90gJo5YM";
String initVector = "RandomInitVector";
Cipher cipher;
private Move()
{
// try
// {
// cipher = Cipher.getInstance("AES/CBC/NoPadding");
// }
// catch (NoSuchAlgorithmException | NoSuchPaddingException e)
// {
// e.printStackTrace();
// }
}
public void saveData(ArrayList<Account> dataToSave)
{
try
{
FileOutputStream fileOut = new FileOutputStream(Config.SERIAL_FILE);
ObjectOutputStream out = new ObjectOutputStream(fileOut);
out.writeObject(encrypt(dataToSave));
out.close();
fileOut.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
@SuppressWarnings("unchecked")
public ArrayList<Account> loadData()
{
ArrayList<Account> loadedData = new ArrayList<Account>();
File f = new File(Config.SERIAL_FILE);
if (f.exists())
{
try
{
FileInputStream fileIn = new FileInputStream(Config.SERIAL_FILE);
ObjectInputStream in = new ObjectInputStream(fileIn);
loadedData = (ArrayList<Account>) in.readObject();
in.close();
fileIn.close();
}
catch (IOException | ClassNotFoundException e)
{
e.printStackTrace();
}
loadedData = decrypt(loadedData);
}
else
{
loadedData = new ArrayList<Account>();
}
return loadedData;
}
private ArrayList<Account> encrypt(List<Account> decrypted)
{
ArrayList<Account> encrypted = new ArrayList<Account>();
try
{
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
for (int i = 0; i < decrypted.size(); i++)
{
try
{
byte[] login = cipher.doFinal(Base64.getDecoder().decode(decrypted.get(i).getLogin().getBytes()));
encrypted.add(new Account(login.toString(), "pass"));
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
catch (InvalidKeyException | InvalidAlgorithmParameterException | UnsupportedEncodingException | NoSuchAlgorithmException | NoSuchPaddingException e)
{
e.printStackTrace();
}
return encrypted;
}
private ArrayList<Account> decrypt(List<Account> encrypted)
{
ArrayList<Account> decrypted = new ArrayList<Account>();
try
{
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
for (int i = 0; i < encrypted.size(); i++)
{
byte[] login = cipher.doFinal(Base64.getDecoder().decode(encrypted.get(i).getLogin()));
decrypted.add(new Account(new String(login), "pass"));
}
}
catch (InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException | NoSuchAlgorithmException | NoSuchPaddingException e)
{
e.printStackTrace();
}
return decrypted;
}
public static Move getMove()
{
if (instance == null)
{
instance = new Move();
}
return instance;
}
}
- Warum verschlüsseln/entschlüsseln Passwörter anstelle von hashing?
- Weil ich Sie die Datei und laden Sie Sie, während Sie eine Anwendung starten.
Du musst angemeldet sein, um einen Kommentar abzugeben.
AES-block-Größe ist immer 128bit, es muss Eingang in vielfachen dieser Zahl.
Kleiner Eingang muss gepolstert sein, um 16 bytes, und der Typ der Polsterung angegeben, um den Algorithmus.
Mit "AES/CBC/PKCS5Padding" wird den trick tun.
Wenn Sie NoPadding, dann müssen Sie implementieren Ihre eigenen Polsterung für die Verschlüsselung, und stellen Sie sicher, um es zu entfernen aus dem resultierenden string in die Entschlüsselung.