我实现了一个Java程序,该程序将使用JSCH在远程服务器中连接并执行命令。问题是,每当我尝试连接到服务器时,都会出现以下异常:
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)
我尝试了在jre / lib和security.provider中添加Bouncy Castle提供程序的解决方案,它可以正常工作。但是我需要使其依赖于项目,因此我尝试在构建路径中添加Bouncy Castle,并在程序中手动添加Bouncy Castle提供程序。但是将其导出到jar后,我仍然收到异常。
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(); } } }
这是我的服务器实用程序,用于处理服务器连接:
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<String> executeCommands(Session s, String commands){ ArrayList<String> result = new ArrayList<String>(); 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; } } }
调试时,我发现当打印机服务尝试连接到服务器时发生错误。
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<String> server_names; private ArrayList<ArrayList<String>> result_server; public PrinterService() { // TODO Auto-generated constructor stub executePrinterMonitoring(); } //Connect to the printer server and process printer monitoring public void executePrinterMonitoring(){ Iterator<Server> it_s = DatabaseUtil.getServers("PRINTER").iterator(); server_names = new ArrayList<String>(); result_server = new ArrayList<ArrayList<String>>(); 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<String> res; ArrayList<ArrayList<String>> res2 = new ArrayList<ArrayList<String>>(); 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 < 10) mon = "0"+month; else mon = ""+month; if(day < 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<ArrayList<String>> s,String servername){ Iterator<String> res1 = s.get(0).iterator(); Iterator<String> res2 = s.get(1).iterator(); ArrayList<String> as = new ArrayList<String>(); ArrayList<String> fres = new ArrayList<String>(); 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 <= 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<String> g = as.iterator(); boolean flag = true; String cl = ""; String std = ""; header = 1; System.out.println("Processing queued results..."); while(res2.hasNext() && g.hasNext()){ if(header <=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("@") && 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<size;i++){ if(fres.get(i).contains("@") && fres.get(i).contains("DOWN")){ down = true; fres.remove(i); i--; size--; continue; } if(down){ if(fres.get(i).contains("@") && !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("<table style=\"border:1px solid black; text-align:center;\" rules=\"all\">"); sb.append("<h1 style=\"margin:0px 0px 0px 50px\">Printer Monitoring as of "+ts.toString()+"</h1>"); sb.append("<tr style=\"background-color: seagreen\">" + "<th style=\"padding: 6px\">SERVER</th>" + "<th style=\"padding: 6px\">QUEUE</th>" + "<th style=\"padding: 6px\">DEV</th>" + "<th style=\"padding: 6px\">STATUS</th>" + "<th style=\"padding: 6px\">JOB FILES</th>" + "<th style=\"padding: 6px\">USER</th>" + "<th style=\"padding: 6px\">PP</th>" + "<th style=\"padding: 6px\">%</th>" + "<th style=\"padding: 6px\">BLKS</th>" + "<th style=\"padding: 6px\">CP</th>" + "<th style=\"padding: 6px\">RNK</th>" + "</tr>"); int counter = 0; Iterator<String> it_s = server_names.iterator(); while(it_s.hasNext()){ sb.append("<tr style=\"background-color: green\"><td style=\"padding: 6px\"><b>"+it_s.next().toUpperCase()+"</b></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>"); Iterator<String> it_res = result_server.get(counter).iterator(); if(result_server.get(counter).isEmpty()){ sb.append("<tr><td></td><td style=\"padding: 6px\"><h5>CLEAN</h5></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>"); } else if(result_server.get(counter).size() == 2){ sb.append("<tr><td></td><td style=\"padding: 6px\"><h5>CLEAN</h5></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td><td></td></tr>"); } else{ while(it_res.hasNext()){ String res = it_res.next(); if(!res.contains("Dev") && !res.contains("----")){ StringTokenizer tok = new StringTokenizer(res," "); sb.append("<tr>"); if(tok.countTokens() == 11){ sb.append("<td style=\"padding: 6px\"></td>"); for(int x=0;x<10;x++){ if(x == 3){ sb.append("<td style=\"padding: 6px\">"+tok.nextToken()+" "+tok.nextToken()+"</td>"); } else{ sb.append("<td style=\"padding: 6px\">"+tok.nextToken()+"</td>"); } } } else{ sb.append("<td style=\"padding: 6px\"></td>"); sb.append("<td style=\"padding: 6px\"></td>"); sb.append("<td style=\"padding: 6px\"></td>"); sb.append("<td style=\"padding: 6px\">"+tok.nextToken()+"</td>"); sb.append("<td style=\"padding: 6px\">"+tok.nextToken()+" "+tok.nextToken()+"</td>"); sb.append("<td style=\"padding: 6px\">"+tok.nextToken()+"</td>"); sb.append("<td style=\"padding: 6px\"></td>"); sb.append("<td style=\"padding: 6px\"></td>"); sb.append("<td style=\"padding: 6px\">"+tok.nextToken()+"</td>"); sb.append("<td style=\"padding: 6px\">"+tok.nextToken()+"</td>"); sb.append("<td style=\"padding: 6px\">"+tok.nextToken()+"</td>"); } sb.append("</tr>"); } } } counter++; } sb.append("</table>"); sb.append("</br></br>"); report = sb.toString(); return report; } }
我还想知道是否有办法使Bouncy Castle轻量化,因为我需要将jar小于2MB,因为我需要将其传输到服务器,并且我没有传输文件的权限> 2MB。
感谢您的帮助。这是我在stackoverflow上的第一篇文章,我真的很喜欢这个社区。谢谢。
我尝试使用服务器中生成的2048位密钥,但仍然收到这些错误。我发现的解决方案是使用其他SSH库,并且可以使用的是Ganymed SSH-2,而不是JSch。感谢您的所有建议和意见。
编辑:此外,该库还轻巧〜1MB。