本文主要是介绍Jsch 深入浅出,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
http://xliangwu.iteye.com/blog/1499764
如果大家熟悉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 host server host
- * @param port ssh 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{
- @Override
- public boolean isEnabled(int level) {
- return true;
- }
- @Override
- public 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 block
- e.printStackTrace();
- }
- String pwd = null;
- try {
- pwd = jhandler.pwd();
- } catch (SftpException e) {
- // TODO Auto-generated catch block
- e.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的问题,而是不能识别的问题。
简单代码如下:
- @Test
- public 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 block
- e.printStackTrace();
- }
- String pwd = null;
- try {
- pwd = jhandler.pwd();
- } catch (SftpException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println(pwd);
- // jhandler.destory();
- }
如果大家熟悉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 host server host
- * @param port ssh 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{
- @Override
- public boolean isEnabled(int level) {
- return true;
- }
- @Override
- public 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 block
- e.printStackTrace();
- }
- String pwd = null;
- try {
- pwd = jhandler.pwd();
- } catch (SftpException e) {
- // TODO Auto-generated catch block
- e.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的问题,而是不能识别的问题。
简单代码如下:
- @Test
- public 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 block
- e.printStackTrace();
- }
- String pwd = null;
- try {
- pwd = jhandler.pwd();
- } catch (SftpException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println(pwd);
- // jhandler.destory();
- }
这篇关于Jsch 深入浅出的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!