title: Java: InvalidAlgorithmParameterException Prime size must be multiple of 64
body: <p>I implemented a Java program that will connect and execute a command in a remote server using JSCH. The problem is that whenever I tried to connect to the server, I got the following exception:</p>
  
  <pre><code>com.jcraft.jsch.JSchException: Session.connect: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 256 to 2048 (inclusive)
  </code></pre>
  
  <p>I tried the solution of adding the Bouncy Castle provider in jre/lib and security.provider and it works. But I need to make it project dependent, so I tried to add Bouncy Castle in my build path and add manually the Bouncy Castle provider in my program. But after exporting it to jar, I am still receiving the exception.</p>
  
  <pre><code>package services;
  
  import java.io.BufferedWriter;
  import java.io.FileWriter;
  import java.io.IOException;
  import java.io.PrintWriter;
  import java.security.Security;
  import java.util.Iterator;
  import java.util.Properties;
  
  import org.bouncycastle.jce.provider.BouncyCastleProvider;
  
  public class MainService {
  
  public MainService() {
      Security.addProvider(new BouncyCastleProvider()); //Adding BouncyCastlePRovider in security
      // TODO Auto-generated constructor stub
      String report = "";
      StringBuilder sb = new StringBuilder();
  
      System.out.println("Running the monitoring...");
      System.out.println("Starting printer monitoring...");
  
      PrinterService ps = new PrinterService(); //A service that connects to the server and executes the commands
      System.out.println("Building report for printer");
  
      sb.append(ps.buildReport());
  
      System.out.println("Done building report for printer");
      System.out.println("Finish printer Monitoring...");
      report = sb.toString();
      writeToFile(report,"fai");
  }
  
  public static void main(String[] args) {
      // TODO Auto-generated method stub
      MainService msrv = new MainService();
  }
  
  public void writeToFile(String contents,String report_name){
      try {
          System.out.println("Writing to file...");
          PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(report_name+".html",false)));
          pw.println(contents);
          pw.close();
          System.out.println("Done writing...");
      } catch (IOException e) {
          e.printStackTrace();
      }
  }
  }
  </code></pre>
  
  <p>Here is my Server utilities that handles server connection:</p>
  
  <pre><code>package utilities;
  
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.util.ArrayList;
  import java.util.Properties;
  
  import javax.swing.JOptionPane;
  
  import com.jcraft.jsch.ChannelExec;
  import com.jcraft.jsch.JSch;
  import com.jcraft.jsch.JSchException;
  import com.jcraft.jsch.Session;
  
  import entity.Server;
  
  public class ServerUtil {
  
  public ServerUtil() {
      // TODO Auto-generated constructor stub
  }
  
  public static Session createSession(Server srv){
      JSch js = new JSch();
      try {
          Session s = js.getSession(srv.getUser().getUsername(), srv.getAddress(), 22);
          s.setPassword(srv.getUser().getPassword());
          Properties config = new Properties();
          config.put("StrictHostKeyChecking", "no");
          config.put("PreferredAuthentications", "password");
          s.setConfig(config);
          s.connect();
          return s;
      } catch (JSchException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          return null;
      }
  }
  
  public static ArrayList&lt;String&gt; executeCommands(Session s, String commands){
      ArrayList&lt;String&gt; result = new ArrayList&lt;String&gt;();
      try {
          System.out.println("Creating channel...");
          ChannelExec channel = (ChannelExec) s.openChannel("exec");
          System.out.println("Channel created.");
          System.out.println("Setting commands...");
          channel.setCommand(commands);
          System.out.println("Commands set.");
          System.out.println("Connecting to channel...");
          channel.connect();
          System.out.println("Channel connected.");
  
          System.out.println("Retrieving output...");
          BufferedReader reader = new BufferedReader(new InputStreamReader(channel.getInputStream()));
          String line;
          while((line = reader.readLine()) != null){
                  result.add(line);
          }
          System.out.println("Output retrieved.");
          channel.disconnect();
          System.out.println("Returning result...");
          return result;
      } catch (JSchException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          return result;
      }catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          return result;
      }
  }
  }
  </code></pre>
  
  <p>While debugging, I find out that the error occurs when the printer service tries to connect to the server.</p>
  
  <pre><code>    package services;
  
  import java.sql.Timestamp;
  import java.util.ArrayList;
  import java.util.Calendar;
  import java.util.Date;
  import java.util.Iterator;
  import java.util.StringTokenizer;
  
  import com.jcraft.jsch.Session;
  
  import entity.Server;
  import utilities.DatabaseUtil;
  import utilities.ServerUtil;
  
  public class PrinterService {
  
      private ArrayList&lt;String&gt; server_names;
      private ArrayList&lt;ArrayList&lt;String&gt;&gt; result_server;
  
      public PrinterService() {
          // TODO Auto-generated constructor stub
          executePrinterMonitoring();
      }
  
      //Connect to the printer server and process printer monitoring
      public void executePrinterMonitoring(){
          Iterator&lt;Server&gt; it_s = DatabaseUtil.getServers("PRINTER").iterator();
          server_names = new ArrayList&lt;String&gt;();
          result_server = new ArrayList&lt;ArrayList&lt;String&gt;&gt;();
          while(it_s.hasNext()){
              Server svr = it_s.next();
              System.out.println("***********START PRINTER SERVER***********");
              String commands = "lpstat -t | sed '/READY/d'; lpstat -W | sed '/READY/d'";
              Session connect = ServerUtil.createSession(svr);
              StringTokenizer tokenize = new StringTokenizer(commands, ";");
              ArrayList&lt;String&gt; res;
              ArrayList&lt;ArrayList&lt;String&gt;&gt; res2 = new ArrayList&lt;ArrayList&lt;String&gt;&gt;();
              System.out.println("Executing commands...");
              while(tokenize.hasMoreTokens()){
                  String comm = tokenize.nextToken().trim();
                  res = ServerUtil.executeCommands(connect, comm);
                  res2.add(res);
              }
              System.out.println("Done executing commands...");
              System.out.println("Processing results...");
              processPMonitoring(res2,svr.getName());
              connect.disconnect();
              System.out.println("***********END PRINTER SERVER***********");
          }
     }
  
      //Get the current date, date - 1, and date - 2
      public String getDate(Calendar cal){
          String mon;
          String dy;
          String dy2;
          String dy3;
          String yr;
          int month = cal.get(Calendar.MONTH)+1;
          int day = cal.get(Calendar.DATE);
          int year = cal.get(Calendar.YEAR);
          if(month &lt; 10)
               mon = "0"+month;
          else
               mon = ""+month;
          if(day &lt; 10){
              dy = "0"+day;
          }
          else{
              dy = ""+day;
          }
          yr = (year+"").substring(2, 4);
          String date =  mon+ "/"+dy+"/"+yr;
  
          return date;
      }
  
      //Split and process the result from the server.
  public void processPMonitoring(ArrayList&lt;ArrayList&lt;String&gt;&gt; s,String servername){
  
          Iterator&lt;String&gt; res1 = s.get(0).iterator();
          Iterator&lt;String&gt; res2 = s.get(1).iterator();
          ArrayList&lt;String&gt; as = new ArrayList&lt;String&gt;();
          ArrayList&lt;String&gt; fres = new ArrayList&lt;String&gt;();
  
          Calendar cal = Calendar.getInstance();
          String date1 = getDate(cal);
          cal.add(Calendar.DATE, -1);
          String date2 = getDate(cal);
          cal.add(Calendar.DATE, -1);
          String date3 = getDate(cal);
          int header = 1;
  
          System.out.println("Checking server:"+servername);
          System.out.println("Getting queued results...");
          while(res1.hasNext()){
              if(header &lt;= 3){
                  //as.add(res1.next());
                  header++;
              }
              else{
                  String curr = res1.next();
                  if(curr.contains("@")){
                      if(curr.contains("STDIN")){
                          String f4 = "";
                          String f5 = "";
                          if(res1.hasNext())
                              f4 = res1.next();
                          if(res1.hasNext())
                              f5 = res1.next();
  
                          if(f4.contains(date1)){
                              as.add(curr);
                          }
                          else if(f4.contains(date2)){
                              as.add(curr);
                          }
                          else if(f4.contains(date3)){
                              as.add(curr);
                          }
                      }
                  }
                  else{
                      String f1 = curr;
                      String f2 = "";
                      String f3 = "";
                      if(res1.hasNext())
                          f2 = res1.next();
                      if(res1.hasNext())
                          f3 = res1.next();
                      if(f2.contains(date1)){
                          as.add(f1);
                      }
                      else if(f2.contains(date2)){
                          as.add(f1);
                      }
                      else if(f2.contains(date3)){
                          as.add(f1 + " - 3 DAYS OLD!");
                      }
                  }
              }
          }
  
          System.out.println("Done queued results...");
          Iterator&lt;String&gt; g = as.iterator();
          boolean flag = true;
          String cl = "";
          String std = "";
          header = 1;
          System.out.println("Processing queued results...");
          while(res2.hasNext() &amp;&amp; g.hasNext()){
              if(header &lt;=2){
                  fres.add(res2.next());
                  header++;
              }
              else{
                  String curr = res2.next();
                  if(curr.contains("@")){
                          fres.add(curr);
                          continue;
                  }
                  if(flag){
                      cl = g.next();
                      if(cl.contains("@") &amp;&amp; cl.contains("STDIN")){
                          continue;
                      }
                      int first_st = cl.indexOf("STDIN");
                      int last_ind = 0;
                      for(last_ind = first_st+1;;last_ind++){
                          //System.out.println("Value of CL:"+cl);
                          //System.out.println("Checking for spaces");
                          //System.out.println("STD CURRENT CHAR:"+cl.charAt(last_ind));
                          if(cl.charAt(last_ind) == ' '){
                              break;
                          }
                      }
                      std = cl.substring(first_st, last_ind);
  
                      flag = false;
  
                      if(fres.get(fres.size()-1).contains(std)){
                          flag = true;
                          continue;
                      }
  
                  }
                  if(curr.contains(std)){
                      fres.add(curr);
                      flag = true;
                  }
              }
          }
  
          System.out.println("Done processing queued results...");
          System.out.println("Post-process queued results...");
          int size = fres.size();
          boolean down = false;
          for(int i=0;i&lt;size;i++){
              if(fres.get(i).contains("@") &amp;&amp; fres.get(i).contains("DOWN")){
                  down = true;
                  fres.remove(i);
                  i--;
                  size--;
                  continue;
              }
              if(down){
                  if(fres.get(i).contains("@") &amp;&amp; !fres.get(i).contains("DOWN")){
                      down = false;
                      continue;
                  }
                  fres.remove(i);
                  i--;
                  size--;
              }
          }
          System.out.println("Done post-processing queued results...");
          //Post-process
          server_names.add(servername);
          result_server.add(fres);
          //fres.add(0,servername);
          //writeToFile(fres,3);
      }
  
      public String buildReport(){
          String report = "";
          StringBuilder sb = new StringBuilder();
          Timestamp ts = new Timestamp(new Date().getTime());
          sb.append("&lt;table style=\"border:1px solid black; text-align:center;\" rules=\"all\"&gt;");
          sb.append("&lt;h1 style=\"margin:0px 0px 0px 50px\"&gt;Printer Monitoring as of "+ts.toString()+"&lt;/h1&gt;");
          sb.append("&lt;tr style=\"background-color: seagreen\"&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;SERVER&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;QUEUE&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;DEV&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;STATUS&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;JOB FILES&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;USER&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;PP&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;%&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;BLKS&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;CP&lt;/th&gt;"
                  + "&lt;th style=\"padding: 6px\"&gt;RNK&lt;/th&gt;"
                  + "&lt;/tr&gt;");
          int counter = 0;
          Iterator&lt;String&gt; it_s = server_names.iterator();
          while(it_s.hasNext()){
              sb.append("&lt;tr style=\"background-color: green\"&gt;&lt;td style=\"padding: 6px\"&gt;&lt;b&gt;"+it_s.next().toUpperCase()+"&lt;/b&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;");
              Iterator&lt;String&gt; it_res = result_server.get(counter).iterator();
              if(result_server.get(counter).isEmpty()){
                  sb.append("&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td style=\"padding: 6px\"&gt;&lt;h5&gt;CLEAN&lt;/h5&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;");
              }
              else if(result_server.get(counter).size() == 2){
                  sb.append("&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td style=\"padding: 6px\"&gt;&lt;h5&gt;CLEAN&lt;/h5&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;");
              }
              else{
                  while(it_res.hasNext()){
                      String res = it_res.next();
                      if(!res.contains("Dev") &amp;&amp; !res.contains("----")){
                          StringTokenizer tok = new StringTokenizer(res," ");
                          sb.append("&lt;tr&gt;");
  
                          if(tok.countTokens() == 11){
                              sb.append("&lt;td style=\"padding: 6px\"&gt;&lt;/td&gt;");
                              for(int x=0;x&lt;10;x++){
                                  if(x == 3){
                                      sb.append("&lt;td style=\"padding: 6px\"&gt;"+tok.nextToken()+" "+tok.nextToken()+"&lt;/td&gt;");
                                  }
                                  else{
                                      sb.append("&lt;td style=\"padding: 6px\"&gt;"+tok.nextToken()+"&lt;/td&gt;");
                                  }
                              }
                          }
                          else{
                              sb.append("&lt;td style=\"padding: 6px\"&gt;&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;"+tok.nextToken()+"&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;"+tok.nextToken()+" "+tok.nextToken()+"&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;"+tok.nextToken()+"&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;"+tok.nextToken()+"&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;"+tok.nextToken()+"&lt;/td&gt;");
                              sb.append("&lt;td style=\"padding: 6px\"&gt;"+tok.nextToken()+"&lt;/td&gt;");
                          }
                          sb.append("&lt;/tr&gt;");
                      }
                  }
              }
              counter++;
          }
          sb.append("&lt;/table&gt;");
          sb.append("&lt;/br&gt;&lt;/br&gt;");
          report = sb.toString();
          return report;
      }
  }
  </code></pre>
  
  <p>I would also like to know if there is a way to make Bouncy Castle a light weight, since I need my jar to be &lt; 2MB since I need to transfer it to a server, and I don't have a permission to transfer a file > 2MB.</p>
  
  <p>Thank you for the help. This is my first post in stackoverflow, and I really love this community. Thanks.</p>