it-swarm.com.de

javax.crypto.IllegalBlockSizeException: Die Eingabelänge muss ein Vielfaches von 16 sein, wenn mit aufgefüllter Chiffre entschlüsselt wird

Ich bekomme einen Entschlüsselungsfehler in der Java-Klasse:

javax.crypto.IllegalBlockSizeException : 
    Input length must be multiple of 16 when decrypting with padded cipher.

Was kann ich tun, um dieses Problem zu lösen?

AKTUALISIEREN:

Ich habe vergessen zu erwähnen, dass es einmal funktioniert und beim zweiten Versuch, es erneut auszuführen, den oben genannten Fehler auslöst.

package com.tb.module.service;
import Java.security.Key;
import Java.security.spec.InvalidKeySpecException;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import Sun.misc.*;

/**
 * This class is used for encrypt and decrypt the  password field.
 *
 */
public class PswdEnc {

    private static final String ALGO = "AES";
    private static final byte[] keyValue = new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't','S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };

    public static String encrypt(String Data) throws Exception {
        Key key = generateKey();
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.ENCRYPT_MODE, key);
        byte[] encVal = c.doFinal(Data.getBytes());
        String encryptedValue = new BASE64Encoder().encode(encVal);
        return encryptedValue;
    }

    public static String decrypt(String encryptedData) throws Exception {
        Key key = generateKey(); 
        Cipher c = Cipher.getInstance(ALGO);
        c.init(Cipher.DECRYPT_MODE, key);
        byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
        byte[] decValue = c.doFinal(decordedValue);
        String decryptedValue = new String(decValue);
        return decryptedValue;
    }


    private static Key generateKey() throws Exception {
        Key key = new SecretKeySpec(keyValue, ALGO);
        return key;
    }

}
19
baburao113

Der von Ihnen verwendete Algorithmus "AES" ist eine Abkürzung für "AES/ECB/NoPadding". Dies bedeutet, dass Sie den AES-Algorithmus mit 128-Bit-Schlüsselgröße und Blockgröße mit dem ECBBetriebsart und keine Polsterung .

Mit anderen Worten: Sie können Daten nur in Blöcken von 128 Bit oder 16 Byte verschlüsseln. Deshalb gibt es diese IllegalBlockSizeException Ausnahme.

Wenn Sie Daten in einer Größe verschlüsseln möchten, die nicht ein Vielfaches von 16 Byte ist, müssen Sie entweder eine Art Auffüllung oder einen Verschlüsselungsdatenstrom verwenden. Beispielsweise könnten Sie den CBC-Modus verwenden (einen Betriebsmodus, der eine Blockverschlüsselung durch Angabe von in eine Streamverschlüsselung umwandelt) "AES/CBC/NoPadding" als Algorithmus oder PKCS5-Auffüllung durch Angabe von "AES/ECB/PKCS5", bei der automatisch einige Bytes am Ende Ihrer Daten in einem ganz bestimmten Format hinzugefügt werden, um die Größe des Chiffretext-Vielfachen von zu ändern 16 Bytes und in einer Weise, dass der Entschlüsselungsalgorithmus versteht, dass er einige Daten ignorieren muss.

Auf jeden Fall empfehle ich dringend, dass Sie jetzt aufhören, was Sie tun, und sich mit einführendem Material zur Kryptographie befassen. Überprüfen Sie beispielsweise Crypto I auf Coursera . Sie sollten die Auswirkungen der Wahl des einen oder anderen Modus, ihre Stärken und vor allem ihre Schwächen sehr gut verstehen. Ohne dieses Wissen ist es sehr einfach, Systeme zu erstellen, die sehr einfach zu brechen sind.


Update: Basierend auf Ihren Kommentaren zu der Frage, verschlüsseln Sie niemals Passwörter, wenn Sie sie in einer Datenbank speichern !!!!! Du solltest das niemals tun. Sie müssen HASH die Passwörter richtig gesalzen, was sich völlig von der Verschlüsselung unterscheidet. Wirklich, bitte, tun Sie nicht das, was Sie versuchen zu tun ... Indem Sie die Passwörter verschlüsseln, können sie entschlüsselt werden. Dies bedeutet, dass Sie als Datenbankmanager, der den geheimen Schlüssel kennt, jedes in Ihrer Datenbank gespeicherte Kennwort lesen können. Entweder du wusstest das und tust etwas sehr, sehr Schlimmes, oder du wusstest das nicht und solltest dich schockieren und damit aufhören.

74
Bruno Reis

Ein paar Anmerkungen:

import Sun.misc.*; Tu das nicht. Es ist kein Standard und es kann nicht garantiert werden, dass es zwischen Implementierungen gleich ist. Es gibt andere Bibliotheken mit Base64-Konvertierung.

byte[] encVal = c.doFinal(Data.getBytes()); Sie setzen hier auf die Standard-Zeichenkodierung. Geben Sie immer an, welche Zeichenkodierung Sie verwenden: byte[] encVal = c.doFinal(Data.getBytes("UTF-8")); Die Standardwerte können sich an verschiedenen Stellen unterscheiden.

Wie @thegrinner darauf hingewiesen hat, müssen Sie die Länge Ihrer Byte-Arrays explizit überprüfen. Wenn eine Diskrepanz besteht, vergleichen Sie sie byteweise, um zu sehen, wo sich der Unterschied einschleicht.

3
rossum

Nun, das ist wegen

sie können Daten nur in Blöcken von 128 Bit oder 16 Byte verschlüsseln. Aus diesem Grund erhalten Sie die IllegalBlockSizeException-Ausnahme ... und Sie können diese Daten direkt in den String verschlüsseln.

sieh dir das an. Versuchen Sie es und Sie werden in der Lage sein, dieses Problem zu lösen

public static String decrypt(String encryptedData) throws Exception {

    Key key = generateKey();
    Cipher c = Cipher.getInstance(ALGO);
    c.init(Cipher.DECRYPT_MODE, key);
    String decordedValue = new BASE64Decoder().decodeBuffer(encryptedData).toString().trim();
    System.out.println("This is Data to be Decrypted" + decordedValue);
    return decordedValue;
}

hoffe das wird helfen.

0
Krishna