title: Java RSA decryption with private key gives BadPaddingException
body: <p>today, I wrote some code to encrypt a String with AES and encrypt the key with RSA. When I try to decrypt the everything, Java gives me a BadPaddingException.
  Here is my code:</p>
  
  <p>Test.java:</p>
  
  <pre><code>import org.apache.commons.codec.binary.Base64;
  import javax.crypto.Cipher;
  import javax.crypto.KeyGenerator;
  import javax.crypto.spec.SecretKeySpec;
  import java.io.BufferedReader;
  import java.io.FileReader;
  import java.io.PrintWriter;
  import java.security.Key;
  import java.security.SecureRandom;
  import java.util.Scanner;
  
  public class Test {
  
  private static String publicName = null;
  private static String privateName = null;
  
  public static void main(String[] args) throws Exception {
      Scanner scanner = new Scanner(System.in);
      System.out.println("Choose an option: \n(1) Decrypt \n(2) Encrypt \n(3) Generate Keypair");
      int choice = scanner.nextInt();
      if(choice == 1) decrypt();
      else if(choice == 2) encrypt();
      else if(choice == 3) makeKeypair();
  }
  
  private static void makeKeypair() throws Exception {
      Scanner scanner = new Scanner(System.in);
      System.out.println("Enter the name of your public key: ");
      publicName = scanner.nextLine() + ".key";
      System.out.println("Enter the name of your private key: ");
      privateName = scanner.nextLine() + ".key";
      KeyMaker keyMaker = new KeyMaker(publicName, privateName);
      keyMaker.generateKeys();
  }
  
  public static void encrypt() throws Exception {
      Scanner scanner = new Scanner(System.in);
      System.out.println("Enter the text you want to encrypt: ");
      String toEncrypt = scanner.nextLine();
      System.out.println("Enter the name of the public key you want to use: ");
      publicName = scanner.nextLine() + ".key";
      Encrypter encrypter = new Encrypter(publicName);
  
      Key key = generateKey();
      String encryptedWithAES = encryptAES(toEncrypt, key);
  
      String encodedKey = java.util.Base64.getEncoder().encodeToString(key.getEncoded());
      String encryptedKey = encrypter.rsaEncrypt(encodedKey);
      String finalOutput = encryptedKey + encryptedWithAES;
  
      System.out.println("Enter the name of the file encrypted file which will be created: ");
      String fileName = scanner.nextLine();
      PrintWriter out = new PrintWriter(fileName + ".txt");
      out.println(finalOutput);
      out.close();
  
      System.out.println("DONE - saved as: " + fileName + ".txt");
      scanner.close();
  }
  
  public static void decrypt() throws Exception {
      Scanner scanner = new Scanner(System.in);
      System.out.println("Enter the name of your encrypted file: ");
      String fileName = scanner.nextLine() + ".txt";
  
      String givenInput = null;
      try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
          String line;
          while ((line = br.readLine()) != null) {
              givenInput = givenInput + line;
          }
      }
      assert givenInput != null;
      String encryptedKey = givenInput.substring(0,172);
      String encryptedWithAES = givenInput.replace(encryptedKey, "");
  
      System.out.println("Enter the name of your private key: ");
      privateName = scanner.nextLine() + ".key";
      Decrypter decrypter = new Decrypter(privateName);
      String decryptedKey = decrypter.rsaDecrypt(encryptedKey);
  
      byte[] decodedKey = java.util.Base64.getDecoder().decode(decryptedKey);
      Key originalKey = new SecretKeySpec(decodedKey, "AES");
  
      String decryptedWithAES = decryptAES(encryptedWithAES, originalKey);
      System.out.println(decryptedWithAES);
      scanner.close();
  }
  
  public static Key generateKey() throws Exception {
      KeyGenerator kg = KeyGenerator.getInstance("AES");
      SecureRandom random = new SecureRandom();
      kg.init(random);
      return kg.generateKey();
  }
  
  private static String encryptAES(String message, Key key) throws Exception {
      Cipher cipher = Cipher.getInstance("AES");
      cipher.init(Cipher.ENCRYPT_MODE,key);
  
      byte[] stringBytes = message.getBytes();
      byte[] raw = cipher.doFinal(stringBytes);
      return Base64.encodeBase64String(raw);
  }
  
  public static String decryptAES(String encrypted, Key key) throws Exception       {
      Cipher cipher = Cipher.getInstance("AES");
      cipher.init(Cipher.DECRYPT_MODE, key);
  
      byte[] raw = Base64.decodeBase64(encrypted);
      byte[] stringBytes = cipher.doFinal(raw);
      return new String(stringBytes, "UTF8");
  }
  }
  </code></pre>
  
  <p>KeyMaker.java:</p>
  
  <pre><code>import java.io.FileOutputStream;
  import java.security.*;
  import java.security.spec.PKCS8EncodedKeySpec;
  import java.security.spec.X509EncodedKeySpec;
  
  public class KeyMaker {
  String publicName;
  String privateName;
  
  public KeyMaker(String publicName, String privateName) {
      this.publicName = publicName;
      this.privateName = privateName;
  }
  
  public void generateKeys() throws Exception{
      KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
      kpg.initialize(1024);
      KeyPair kp = kpg.genKeyPair();
  
      PrivateKey privateKey = kp.getPrivate();
      PublicKey publicKey = kp.getPublic();
  
      X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(
              publicKey.getEncoded());
      FileOutputStream fos = new FileOutputStream(publicName);
      fos.write(x509EncodedKeySpec.getEncoded());
      fos.close();
  
      PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(
              privateKey.getEncoded());
      fos = new FileOutputStream(privateName);
      fos.write(pkcs8EncodedKeySpec.getEncoded());
      fos.close();
  }
  }
  </code></pre>
  
  <p>Encrypter.java:</p>
  
  <pre><code>import org.apache.commons.codec.binary.Base64;
  import javax.crypto.Cipher;
  import java.io.*;
  import java.security.KeyFactory;
  import java.security.PublicKey;
  import java.security.spec.X509EncodedKeySpec;
  
  public class Encrypter {
  String keyFileName;
  
  public Encrypter(String keyFileName) {
      this.keyFileName = keyFileName;
  }
  
  public String rsaEncrypt(String data) throws Exception {
      PublicKey pubKey = readPublicKeyFromFile(keyFileName);
              byte[] utf8 = data.getBytes("UTF-8");
      Cipher cipher = Cipher.getInstance("RSA");
  
      cipher.init(Cipher.ENCRYPT_MODE, pubKey);
      byte[] enc = cipher.doFinal(Base64.encodeBase64(utf8));
      return Base64.encodeBase64String(enc);
  }
  
  private PublicKey readPublicKeyFromFile(String keyFileName) throws Exception {
      File filePublicKey = new File(keyFileName);
      FileInputStream fis = new FileInputStream(keyFileName);
      byte[] encodedPublicKey = new byte[(int) filePublicKey.length()];
      fis.read(encodedPublicKey);
      fis.close();
  
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(
              encodedPublicKey);
      PublicKey pubKey = keyFactory.generatePublic(publicKeySpec);
      return pubKey;
  }
  }
  </code></pre>
  
  <p>Decrypter.java:</p>
  
  <pre><code>import org.apache.commons.codec.binary.Base64;
  import javax.crypto.Cipher;
  import java.io.*;
  import java.security.KeyFactory;
  import java.security.PrivateKey;
  import java.security.spec.PKCS8EncodedKeySpec;
  
  public class Decrypter {
  String keyFileName;
  
  public Decrypter(String keyFileName) {
      this.keyFileName = keyFileName;
  }
  
  public String rsaDecrypt(String str) throws Exception {
      PrivateKey privateKey = readPrivateKeyFromFile(keyFileName);
      Cipher cipher = Cipher.getInstance("RSA");
  
      cipher.init(Cipher.DECRYPT_MODE, privateKey);
      byte[] dec = Base64.decodeBase64(str);
      byte[] utf8 = cipher.doFinal(Base64.decodeBase64(dec));
      return Base64.encodeBase64String(utf8);
  
  }
  
  private PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception {
      File filePrivateKey = new File(keyFileName);
      FileInputStream fis = new FileInputStream(keyFileName);
      byte[] encodedPrivateKey = new byte[(int) filePrivateKey.length()];
      fis.read(encodedPrivateKey);
      fis.close();
  
      KeyFactory keyFactory = KeyFactory.getInstance("RSA");
      PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(
              encodedPrivateKey);
      PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
      return privateKey;
  }
  }
  </code></pre>