# javax.crypto.BadPaddingException - was ist das genau?



## qwert (8. Okt 2014)

Hallo,

bei folgendem Codesegment:

```
Cipher cipher = Cipher.getInstance("RSA");
		  cipher.init(Cipher.DECRYPT_MODE, privKey);
		  byte[] cipherData = cipher.doFinal(enc_msg);
```
tritt eine javax.crypto.BadPaddingException auf. Was bedeutet das genau (die Übersetzung kenne ich, kann mir daraus aber nichts erschließen) und wie kann ich das verhindern?

Hintergrund:
Ich schreibe eine Applikation zum Austausch von Daten zwischen unterschiedlichen Geräten. Dies erfolgt verschlüsselt. Wenn ich nun meinem Programm verschlüsselte Daten in die Datenbank eintragen und auslesen lasse, so funktioniert das einwandfrei.
Das selbe, unveränderte, Ver- und Entschlüsselungsmodul verwende ich auch in einer App auf Android. Auch hier funktioniert es einwandfrei, wenn das Gerät Daten einträgt und ausliest.
Der Fehler tritt nur dann auf, wenn Ein- und Auslesegerät verschieden sind, ich die Daten also mit dem PC einetragen habe, mit dem Smartphone aber auslesen möchte, oder anders herum.

Vielen Dank schonmal für eure Unterstützung .


----------



## Ch4t4r (8. Okt 2014)

Hey,

Um dir genau zu helfen müssten wir auch die Verschlüsselung sehen. Ich würde, ohne sie gesehen zu haben, mal davon ausgehen, dass du an irgendeiner stelle einen Byte auslässt oder beide Geräte verschiedene Spezifikationen für RSA verwenden. Generell solltest du auch lieber symmetrisch verschlüsseln, es ist schneller und asymmetrische Verschlüsselungen können nur eine maximale Anzahl an bytes verschlüsseln.


----------



## qwert (8. Okt 2014)

Gut, dann poste ich halt ein wenig mehr , ich hoffe, es sieht sich dann noch jemand an .

Hier das Modul, das für die RSA-Verschlüsselung zuständig ist:

```
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class Kryptomodul {
    public static String AESPassphrase = "";
    public static byte[] encrypt(String msg, PublicKey pubKey) {
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            byte[] cipherData = cipher.doFinal(msg.getBytes());
            return cipherData;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static byte[] decrypt(byte[] enc_msg, PrivateKey privKey) {
        try {
          Cipher cipher = Cipher.getInstance("RSA");
          cipher.init(Cipher.DECRYPT_MODE, privKey);
          byte[] cipherData = cipher.doFinal(enc_msg);
          return cipherData;
        } catch(IllegalBlockSizeException err) {
            err.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static PublicKey readPublicKeyFromFile(File f) {
        try {
            // Read Public Key.
            BufferedReader br = new BufferedReader(new FileReader(f));
            byte[] encodedPublicKey = hexStringToByteArray(br.readLine());
            br.close();
     
            // Generate KeyPair.
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
                    encodedPublicKey);
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
         
            return publicKey;
        } catch(IOException err) {
            err.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    public static PrivateKey readPrivateKeyFromFile(File f) {
        // Private Key lesen
        try {     
            // Read Private Key.
            BufferedReader br = new BufferedReader(new FileReader(f));
            String line = br.readLine();
            line = AESModul.getDecrypted(line, AESPassphrase);
            if(line == null) {
                br.close();
                return null;
            }
            byte[] encodedPrivateKey = hexStringToByteArray(line);
            br.close();
     
            // Generate KeyPair.
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");     
            PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
                    encodedPrivateKey);
            PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

            return privateKey;
        } catch(IOException err) {
            err.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    public static PublicKey getKeyFromString(String keystring) {
        try {
            // Read Public Key.
            byte[] encodedPublicKey = hexStringToByteArray(keystring); 
            // Generate KeyPair.
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
                    encodedPublicKey);
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
         
            return publicKey;
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;        
    }
    public static String getHexString(byte[] b) {
        String result = "";
        for (int i = 0; i < b.length; i++) {
            result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
        }
        return result;
    }
    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                                 + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }
    public static void savePrivateKey(PrivateKey privKey, String filename) {
        //mit AES verschlüsseln:
        File f = new File(Konstanten.EXTERNAL_STORAGE+Konstanten.DIR+filename);
        
        try {
            // Store Private Key.
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
                    privKey.getEncoded());
            BufferedWriter bw = new BufferedWriter(new FileWriter(f));
            bw.write(AESModul.getEncrypted(getHexString(pkcs8EncodedKeySpec.getEncoded()),AESPassphrase));
            bw.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void savePublicKey(PublicKey pubKey, String filename) {
        File f = new File(Konstanten.EXTERNAL_STORAGE+Konstanten.DIR+filename);
        // Public Key sichern
        try {
            // Store Public Key.
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
                    pubKey.getEncoded());
            BufferedWriter bw = new BufferedWriter(new FileWriter(f));
            bw.write(getHexString(x509EncodedKeySpec.getEncoded()));
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static KeyPair generateKeyPair() {
        try {
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
            kpg.initialize(2048);
            return kpg.genKeyPair();
        } catch(NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }
}
```

Und damit der private Key nicht so leicht ausgelesen werden kann ist der noch mit AES verschlüsselt:

```
import java.security.MessageDigest;
import java.util.Arrays;

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

public class AESModul {
    //assert: keyStr.length() > 0
    public static String getDecrypted(String enckey, String keyStr) {
        try  {
            byte[] key = (keyStr).getBytes("UTF-8");
            MessageDigest sha = MessageDigest.getInstance("MD5");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16); 
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
            
            
            byte[] crypted2 = MyBase64.decode(enckey);
        
            Cipher cipher2 = Cipher.getInstance("AES");
            cipher2.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] cipherData2 = cipher2.doFinal(crypted2);
            return new String(cipherData2);
                } catch(Exception err) {
            err.printStackTrace();
        }        
        return null;
    }
    public static String getEncrypted(String pubkey, String keyStr) {
        try  {
            byte[] key = (keyStr).getBytes("UTF-8");
            MessageDigest sha = MessageDigest.getInstance("MD5");
            key = sha.digest(key);
            key = Arrays.copyOf(key, 16); 
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
             
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            byte[] encrypted = cipher.doFinal(pubkey.getBytes());
        
            String geheim = MyBase64.encode(encrypted);
            return geheim;
            
        } catch(Exception err) {
            err.printStackTrace();
        }
        return null;
    }
}
```

Es ist aufgrund der gegebene Konstellation leider nicht möglich auf eine asymmetrische Verschlüsselung zu verzichten .


----------



## crypto (8. Okt 2014)

Erstmal eine frage :
Wieso wird bei dir die nachricht per RSA verschlüsselt ?
Siehe Hybrides Kryptosystem...

Zu deiner frage:
Die BadPaddingException wird geworfern,weil du vermutlich versuchst nachrichten 
zu verschlüsseln, die nicht gleich der modul-länge sind (bsp. länger als 2048 bit)

Mein tip:
 - Verschlüssel die Nachrichten per sym. Verfahren (du hast ja bereits methoden für AES)
 - Verschlüssel den AES-key per RSA
 - Versende Daten + enc AES-key


----------



## qwert (8. Okt 2014)

> Zu deiner frage:
> Die BadPaddingException wird geworfern,weil du vermutlich versuchst nachrichten
> zu verschlüsseln, die nicht gleich der modul-länge sind (bsp. länger als 2048 bit)



Was meinst du damit genau? Ich wusste bisher nicht, dass eine bestimmte Länge der Nachricht Voraussetzung ist.

Danke für deinen Tipp, aber für meinen Fall ist der leider nicht anwendbar (bzw. vorsichtiger ausgedrückt: für mich nicht anwendbar, weil ich keine Lösung kenne  ). Ich bin auf RSA angewiesen.


----------



## qwert (8. Okt 2014)

Ok, nachdenken hilft manchmal . Ich sehe eine Lösung mit Kombination der beiden Verfahren. Allerdings ist der Nachteil darin, dass die Infrastruktur für mein derzeitiges System vollständig steht und es ein nicht unerheblicher Aufwand wäre, das ganze umzustellen - unter Berücksichtigung des Problems, dass ich am Freitag fertig sein muss... :/


----------



## Tobse (8. Okt 2014)

Eine BadPaddingException bedeutet normalerweise, dass der Schlüssel nicht stimmt. Denn mit falschem Schlüssel wird nur kauderwelsch entschlüsselt und kein valides Padding, siehe Padding (Informatik)

Du gibts beim erstellen des RSA ciphers kein Mode und kein Padding an, daher kann es auch sein, dass der Schlüssel zwar stimmt aber verschiedene Paddings fürs ver- und Entschlüsseln benutzt werden.
Cipher#getInstance "RSA" ist das gleiche wie "RSA/ECB/PKCS1Padding" und das ist schlecht denn der ECB macht deine Verschlüsselung sinnlos, siehe Block cipher mode of operation - Wikipedia, the free encyclopedia.
Du kannst also RSA/CBC/PKCS1Padding nehmen und hast eine schlechte performance - oder du benutzt, wie bereits vorgeschlagen, ein Hybrid aus RSA und AES (PGP-Standard).
Wenn die BadPaddingException allerdings fliegt, weil du den falschen Schlüssel nimmst können wir dir nicht helfen, dafür kennen wir deine Software zu schlecht.


----------



## qwert (8. Okt 2014)

Ok, danke. Dann hab ich mich für die schlechte Performance entschieden , denn bei mir geht es ausschließlich um sehr kurze Daten.


----------



## qwert (9. Okt 2014)

Ich hab es jetzt so abgeändert:

```
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class Kryptomodul {
    public static String AESPassphrase = "";
    public static byte[] encrypt(String msg, PublicKey pubKey) {
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            byte[] cipherData = cipher.doFinal(msg.getBytes());
            return cipherData;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static byte[] decrypt(byte[] enc_msg, PrivateKey privKey) {
        try {
          Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
          cipher.init(Cipher.DECRYPT_MODE, privKey);
          byte[] cipherData = cipher.doFinal(enc_msg);
          return cipherData;
        } catch(IllegalBlockSizeException err) {
            err.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }
    public static PublicKey readPublicKeyFromFile(File f) {
        try {
            // Read Public Key.
            BufferedReader br = new BufferedReader(new FileReader(f));
            byte[] encodedPublicKey = hexStringToByteArray(br.readLine());
            br.close();
     
            // Generate KeyPair.
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
                    encodedPublicKey);
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
         
            return publicKey;
        } catch(IOException err) {
            err.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    public static PrivateKey readPrivateKeyFromFile(File f) {
        // Private Key lesen
        try {     
            // Read Private Key.
            BufferedReader br = new BufferedReader(new FileReader(f));
            String line = br.readLine();
            line = AESModul.getDecrypted(line, AESPassphrase);
            if(line == null) {
                br.close();
                return null;
            }
            byte[] encodedPrivateKey = hexStringToByteArray(line);
            br.close();
     
            // Generate KeyPair.
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");     
            PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
                    encodedPrivateKey);
            PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);

            return privateKey;
        } catch(IOException err) {
            err.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
    public static PublicKey getKeyFromString(String keystring) {
        try {
            // Read Public Key.
            byte[] encodedPublicKey = hexStringToByteArray(keystring); 
            // Generate KeyPair.
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
                    encodedPublicKey);
            PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
         
            return publicKey;
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;        
    }
    public static String getHexString(byte[] b) {
        String result = "";
        for (int i = 0; i < b.length; i++) {
            result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
        }
        return result;
    }
    public static byte[] hexStringToByteArray(String s) {
        int len = s.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                                 + Character.digit(s.charAt(i+1), 16));
        }
        return data;
    }
    public static void savePrivateKey(PrivateKey privKey, String filename) {
        //mit AES verschlüsseln:
        File f = new File(Konstanten.EXTERNAL_STORAGE+Konstanten.DIR+filename);
        
        try {
            // Store Private Key.
            PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
                    privKey.getEncoded());
            BufferedWriter bw = new BufferedWriter(new FileWriter(f));
            bw.write(AESModul.getEncrypted(getHexString(pkcs8EncodedKeySpec.getEncoded()),AESPassphrase));
            bw.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void savePublicKey(PublicKey pubKey, String filename) {
        File f = new File(Konstanten.EXTERNAL_STORAGE+Konstanten.DIR+filename);
        // Public Key sichern
        try {
            // Store Public Key.
            X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
                    pubKey.getEncoded());
            BufferedWriter bw = new BufferedWriter(new FileWriter(f));
            bw.write(getHexString(x509EncodedKeySpec.getEncoded()));
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static KeyPair generateKeyPair() {
        try {
            KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
            kpg.initialize(2048);
            return kpg.genKeyPair();
        } catch(NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
}
```
Allerdings immer noch der selbe Fehler . Und die Zeile:

```
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
```
kann ich nicht ändern, denn was anderes als "RSA" ist kein gültiger Wert.


----------



## qwert (9. Okt 2014)

Hab nun die Kodierung des Strings auf Base64 geändert und es scheint sich gebessert zu haben.


----------

