首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > JavaScript >

Jsch 深入显出

2012-07-30 
Jsch 深入浅出?如果大家熟悉Linux的话,一定对ssh,sftp,scp等命令非常熟悉。ssh是一个安全协议,用来在不同系

Jsch 深入浅出

?

如果大家熟悉Linux的话,一定对ssh,sftp,scp等命令非常熟悉。ssh是一个安全协议,用来在不同系统或者服务器之间进行安全连接。ssh 在连接和传送的过程中会加密所有的数据。具体的解释,大家可以参考百度百科的文档。地址为:http://baike.baidu.com/view/16184.htm

但是SSH一般是基于客户端的或者Linux命令行的。比如客户端的工具:OpenSSH,putty,SSH Tectia;在linux上大家可以通过ssh username@host连接到所要想连接的主机。但是如果在J2EE中,如何实现SSH呢?进而可以实现SCP,SFTP的功能呢?下面介绍的JSCH就可以实现下边的功能。

JSCH是一个纯粹的用java实现SSH功能的java ?library. 官方地址为:http://www.jcraft.com/jsch/

GitHub 地址为:https://github.com/vngx/vngx-jsch

mvn 配置如下:

<dependency><groupId>com.jcraft</groupId><artifactId>jsch</artifactId><version>0.1.46</version></dependency>

?

下面简单介绍下JSCH的特点:

1.基于DSA和RSA加密。

2.可以实现4中认证机制。分别是:

(1i): password

(2i): publickey(DSA,RSA)

(3i): keyboard-interactive

(4i): gss-api-with-mic

3.生成public/private key pair.

4.执行bash script 等脚本

5.可以通过HTTP/SOCK5 proxy

6.支持常见SSH1协议和SSH2协议

我们日常用到的JSCH主要是基于是密码认证和private key 认证。

基于密码认证的比较简单。简单代码如下:

?

?

public class JschHandler {private static final Logger log = LoggerFactory.getLogger(JschHandler.class);public static final String SFTP_PROTOCAL = "sftp";private String username;private String host;private int port;private String identity;private UserInfo userInfo;private JSch jsch = null;protected Session session = null;private boolean firstInit = false;private int authType = -1;/** * Private/public key authorization * @param username user account * @param hostserver host * @param portssh port * @param identity the path of private key file. * @see http://www.jcraft.com/jsch/ */public JschHandler(String username,String host,int port,String identity){this.username = username;this.host = host;this.port = port;this.identity = identity;firstInit = false;jsch = new JSch();authType = 0 ;}/** * Password authorization * @param username * @param host * @param port * @param userInfo User information for authorization * @see com.jcraft.jsch.UserInfo * @see http://www.jcraft.com/jsch/ */public JschHandler(String username,String host,int port,UserInfo userInfo){this.username = username;this.host = host;this.port = port;this.userInfo = userInfo;firstInit = false;jsch = new JSch();authType = 1;}/** *  * Initialize SSH session. * When the parameters is not right, It will throw an JSchException. * @throws MessageServicerException * @see com.jcraft.jsch.JSch */@SuppressWarnings("static-access")protected void init() throws JSchException{try {validate();log.info("JSCH identity:"+identity);jsch.setLogger(new JschLogger());jsch.setConfig("StrictHostKeyChecking", "no");if(authType==0) jsch.addIdentity(identity);session = jsch.getSession(username, host, port);if(authType==1) session.setUserInfo(userInfo);session.connect();log.info("JSCH session connect success.");} catch (JSchException e) {log.error(e.getMessage());throw e;}}/** * Validate parameters * @throws JSchException */private void validate() throws JSchException{if(firstInit) return;if(username==null||username.isEmpty()){throw new JSchException("Parameter:username is empty.");}if(host==null||host.isEmpty()){throw new JSchException("Parameter:host is empty.");}else{try {InetAddress inet = InetAddress.getByName(host);host = inet.getHostAddress();log.info("JSCH connection address:"+host);} catch (UnknownHostException e) {throw new JSchException(e.getMessage(),e);}}if(authType==0&&(identity==null||identity.isEmpty())){throw new JSchException("Parameter:identity is empty.");}if(authType==1&&(userInfo==null)){throw new JSchException("Parameter:userInfo is empty.");}firstInit = true;}/** * release connections. * @author  */protected void destory(){if(session!=null) session.disconnect();log.info("JSCH session destory");}private static class JschLogger implements com.jcraft.jsch.Logger{@Overridepublic boolean isEnabled(int level) {return true;}@Overridepublic void log(int level, String message) {System.out.println(String.format("[JSCH --> %s]", message));}}public void setUserInfo(UserInfo userInfo) {this.userInfo = userInfo;}}

?? ?client

?

public static class MyUserInfo implements UserInfo, UIKeyboardInteractive {public String getPassword() {return null;}public boolean promptYesNo(String str) {Object[] options = { "yes", "no" };int foo = JOptionPane.showOptionDialog(null, str, "Warning",JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,null, options, options[0]);return foo == 0;}String passphrase;JTextField passphraseField = (JTextField) new JPasswordField(20);public String getPassphrase() {return passphrase;}public boolean promptPassphrase(String message) {Object[] ob = { passphraseField };int result = JOptionPane.showConfirmDialog(null, ob, message,JOptionPane.OK_CANCEL_OPTION);if (result == JOptionPane.OK_OPTION) {passphrase = passphraseField.getText();return true;} else {return false;}}public boolean promptPassword(String message) {return true;}public void showMessage(String message) {JOptionPane.showMessageDialog(null, message);}final GridBagConstraints gbc = new GridBagConstraints(0, 0, 1, 1, 1, 1,GridBagConstraints.NORTHWEST, GridBagConstraints.NONE,new Insets(0, 0, 0, 0), 0, 0);private Container panel;public String[] promptKeyboardInteractive(String destination,String name, String instruction, String[] prompt, boolean[] echo) {panel = new JPanel();panel.setLayout(new GridBagLayout());gbc.weightx = 1.0;gbc.gridwidth = GridBagConstraints.REMAINDER;gbc.gridx = 0;panel.add(new JLabel(instruction), gbc);gbc.gridy++;gbc.gridwidth = GridBagConstraints.RELATIVE;JTextField[] texts = new JTextField[prompt.length];for (int i = 0; i < prompt.length; i++) {gbc.fill = GridBagConstraints.NONE;gbc.gridx = 0;gbc.weightx = 1;panel.add(new JLabel(prompt[i]), gbc);gbc.gridx = 1;gbc.fill = GridBagConstraints.HORIZONTAL;gbc.weighty = 1;if (echo[i]) {texts[i] = new JTextField(20);} else {texts[i] = new JPasswordField(20);}panel.add(texts[i], gbc);gbc.gridy++;}if (JOptionPane.showConfirmDialog(null, panel, destination + ": "+ name, JOptionPane.OK_CANCEL_OPTION,JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION) {String[] response = new String[prompt.length];for (int i = 0; i < prompt.length; i++) {response[i] = texts[i].getText();}return response;} else {return null; // cancel}}}

?@Test

public void testSftp() throws JSchException{UserInfo userInfo = new MyUserInfo();JftpHandler jhandler = new JftpHandler("username","hostname",22,userInfo);try {jhandler.init();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}String pwd = null;try {pwd = jhandler.pwd();} catch (SftpException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(pwd);//jhandler.destory();}
?

基于private key 认证的有点费时。关于如何配置private/public key认证,大家通过google来配置。简单流程如下:

1.在linux 下执行ssh-keygen -t dsa /ssh-keygen -t rsa.这样就会成一对对应的public key 和private key.比如id_dsa_1024,id_dsa_1024.pub.

2. 把public key(id_dsa_1024.pub)复制到想要连接的服务器上,放到对应用户的.ssh目录下。

3.

cd ~/.ssh

#将Client的公钥放入Server的信任列表

cat id_dsa_1024.pub >> authorized_keys

#更新权限,很重要

chmod 0600 *从此以后Client SSH登录Server就不要手工输入密码了

配置完成以后,重新登录一下,就可以发现不用输入密码就可以实现远程登录了。

由于现在基于SSH协议的算法很多,加密和解密的算法也不一样。目前Jsch只支持OpenSSH和SSH 1生成的private/public key.

所以当你们发现不能通过private/public key认证的时候,不是jsch的问题,而是不能识别的问题。

简单代码如下:

?

?

?

@Testpublic void testSftp() throws JSchException{JftpHandler jhandler = new JftpHandler("username","hostname",22,"C:\\data\\id_dsa_2048_a");try {jhandler.init();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}String pwd = null;try {pwd = jhandler.pwd();} catch (SftpException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(pwd);//jhandler.destory();}
?

上面只是对JSCH的简单介绍,希望对大家有所用户。。。。Jsch 深入显出

热点排行