文档章节

自己制作SSH客户端:二、叩响大门

围观
 围观
发布于 2015/02/15 14:50
字数 1768
阅读 1278
收藏 60

现在基于上面制作的SocketClient可以进行各种Socket协议的收发操作。但是要注意,缓冲区大小有可能会造成的粘包问题。

我们开始连接服务器的ssh服务

ClientSocket client = new ClientSocket(socket);
client.setClientListener(listener);
client.start();
ssh = new SSH(client.getName());

可以看到我们这里已经实现了一个ClientListener的接口回调,这里面会长期与服务器进行打交道。

static ClientListener listener = new ClientListener() {
@Override
public void onSendData(ClientSocket client, byte[] data) {
System.out.println("发送数据");
}
@Override
public void onReceiveData(ClientSocket client, byte[] data) {
System.out.println("收到数据:" + client.getName());
System.out.println("" + new String(data));
ClientSocket.outHexByteArgs(data);
switch (index) {
case 0:// 协商协议版本
String version = new String(data);
String serverVersion = ssh.version(version);
client.send(data);
System.out.println("ServerVersion:" + serverVersion
+ "|发送协商协议版本请求");
index++;
break;
case 1:// 协商加密算法
client.send(data);
System.out.println("发送协商加密算法");
index++;
break;
case 2:
}
}
@Override
public void onConnect(ClientSocket client) {
System.out.println("连接成功");
}
@Override
public void onClose(ClientSocket client) {
System.out.println("关闭");
}
};

这里我已经实现了前两个握手;

在整个通讯过程中,为实现 SSH的安全连接,服务器端与客户端要经历如下五个阶段:

    * 版本号协商阶段,SSH目前包括 SSH1SSH2两个版本, 双方通过版本协商确定使用的版本

    * 密钥和算法协商阶段,SSH支持多种加密算法, 双方根据本端和对端支持的算法,协商出最终使用的算法

    * 认证阶段,SSH客户端向服务器端发起认证请求, 服务器端对客户端进行认证

    * 会话请求阶段, 认证通过后,客户端向服务器端发送会话请求

    * 交互会话阶段 ,会话请求通过后,服务器端和客户端进行信息的交互

1 . 版本号协商阶段

   1. 服务器打开端口 22,等待客户端连接。

   2. 客户端向服务器端发起 TCP初始连接请求,TCP连接建立后,服务器向客户端发送第一个报文,包括版本标志字符串,格式为“SSH<主协议版本号>.<次协议版本号><软件版本号>”,协议版本号由主版本号和次版本号组成,软件版本号主要是为调试使用。

   3. 客户端收到报文后,解析该数据包,如果服务器端的协议版本号比自己的低,且客户端能支持服务器端的低版本,就使用服务器端的低版本协议号,否则使用自己的协议版本号。

   4. 客户端回应服务器一个报文,包含了客户端决定使用的协议版本号。服务器比较客户端发来的版本号,决定是否能同客户端一起工作。

   5. 如果协商成功,则进入密钥和算法协商阶段,否则服务器端断开 TCP连接。

Note 版本号协商阶段报文都是采用明文方式传输的。

 

2. 密钥和算法协商阶段

   1. 服务器端和客户端分别发送算法协商报文给对端,报文中包含自己支持的公钥算法列表、加密算法列表、MACMessage Authentication Code,消息验证码)算法列表、压缩算法列表等;

   2. 服务器端和客户端根据对端和本端支持的算法列表得出最终使用的算法。

   3. 服务器端和客户端利用 DH交换(Diffie-Hellman Exchange)算法、主机密钥对等参数,生成会话密钥和会话 ID

 

      通过以上步骤,服务器端和客户端就取得了相同的会话密钥和会话ID

          * 对于后续传输的数据,两端都会使用会话密钥进行加密和解密,保证了数据传送的安全

          * 在认证阶段,两端会使用会话 ID用于认证过程。

      Note

             在协商阶段之前,服务器端已经生成 RSA DSA密钥对,他们主要用于参与会话密钥的生成。

 

 

3. 认证阶段

   1. 客户端向服务器端发送认证请求,认证请求中包含用户名、认证方法、与该认证方法相关的内容(如:password认证时,内容为密码)。

   2. 服务器端对客户端进行认证,如果认证失败,则向客户端发送认证失败消息,其中包含可以再次认证的方法列表。

   3. 客户端从认证方法列表中选取一种认证方法再次进行认证。

   4. 该过程反复进行, 直到认证成功或者认证次数达到上限, 服务器关闭连接为止。

 

SSH提供两种认证方式:

   1. password认证:客户端向服务器发出 password认证请求,将用户名和密码加密后发送给服务器;服务器将该信息解密后得到用户名和密码的明文,与设备上保存的用户名和密码进行比较,并返回认证成功或失败的消息。

   2. publickey 认证:采用数字签名的方法来认证客户端。目前,设备上可以利用RSA DSA两种公共密钥算法实现数字签名。客户端发送包含用户名、公共密钥和公共密钥算法的 publickey 认证请求给服务器端。服务器对公钥进行合法性检查,如果不合法,则直接发送失败消息;否则,服务器利用数字签名对客户端进行认证,并返回认证成功或失败的消息

 

SSH2.0还提供了 password-publickey 认证和 any 认证:

   1. password-publickey 认证:指定该用户的认证方式为 password  publickey认证同时满足。客户端版本为 SSH1的用户只要通过其中一种认证即可登录;客户端版本为 SSH2的用户必须两种认证都通过才能登录。

   2. any认证:指定该用户的认证方式可以是 password,也可以是 publickey

 

4.会话请求阶段

   1. 服务器等待客户端的请求;

   2. 认证通过后,客户端向服务器发送会话请求;

   3. 服务器处理客户端的请求。请求被成功处理后, 服务器会向客户端回应 SSH_SMSG_SUCCESS包,SSH进入交互会话阶段;否则回应 SSH_SMSG_FAILURE包,表示服务器处理请求失败或者不能识别请求。

 

5.交互会话阶段

在这个模式下,数据被双向传送:

   1. 客户端将要执行的命令加密后传给服务器;

   2. 服务器接收到报文,解密后执行该命令,将执行的结果加密发还给客户端;

   3. 客户端将接收到的结果解密后显示到终端上.


所有资料都是自己找,好在有OpenSSH,后期找不到资料还可以参阅源码。


关于SSH的协议的描述请移步(感谢两位发布的博文,让我找到些参考资料):

http://blog.csdn.net/macrossdzh/article/details/5691924

http://blog.sina.com.cn/s/blog_3f76315e0101rst2.html


© 著作权归作者所有

围观
粉丝 12
博文 20
码字总数 5747
作品 0
青岛
程序员
私信 提问
2011年12月编程语言排行榜:C#快取代C++的第三名

TIOBE 于今日公布了2011年12月编程语言排行榜。虽然前三的位置还是Java、C 和 C++,但是第三位置恐将易主。从 2001年开始,TIOBE指数排行榜第三的这个位置,C++编程语言一直处于坐的比较稳定...

DustLeon
2011/12/09
253
1
12月编程语言排行榜:C#快取代C++的第三名

TIOBE 于今日公布了2011年12月编程语言排行榜。虽然前三的位置还是Java、C 和 C++,但是第三位置恐将易主。 从2001年开始,TIOBE指数排行榜第三的这个位置,C++编程语言一直坐的比较稳定。虽...

红薯
2011/12/06
8.2K
66
2017智慧建筑(IB)峰会叩响建筑智慧化的大门

阿里巴巴为什么说智慧建筑元年来了?相信吗?建筑是会有生命的! 借助于云计算、物联网等新技术的迅猛发展,传统的建筑正从单一的钢筋水泥,演变成具有感知、交互、自我适应和生长的“生命体...

玄学酱
2018/04/16
0
0
SecureCRT通过密钥登录

说明: 一般的密码方式登录容易被密码暴力破解。所以一般我们会将 SSH 的端口设置为默认22以外的端口,或者禁用root账户登录。其实可以通过密钥登录这种方式来更好地保证安全。 密钥形式登录...

Dhfijk
2017/05/08
0
0
设置 SSH 通过密钥登录

设置 SSH 通过密钥登录 from : http://www.runoob.com/w3cnote/set-ssh-login-key.html 我们一般使用 PuTTY 等 SSH 客户端来远程管理 Linux 服务器。但是,一般的密码方式登录,容易有密码被...

vv_2018
2016/10/26
16
0

没有更多内容

加载失败,请刷新页面

加载更多

mysql-connector-java升级到8.0后保存时间到数据库出现了时差

在一个新项目中用到了新版的mysql jdbc 驱动 <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.18</version> ......

ValSong
今天
5
0
Spring Boot 如何部署到 Linux 中的服务

打包完成后的 Spring Boot 程序如何部署到 Linux 上的服务? 你可以参考官方的有关部署 Spring Boot 为 Linux 服务的文档。 文档链接如下: https://docs.ossez.com/spring-boot-docs/docs/r...

honeymoose
今天
6
0
Spring Boot 2 实战:使用 Spring Boot Admin 监控你的应用

1. 前言 生产上对 Web 应用 的监控是十分必要的。我们可以近乎实时来对应用的健康、性能等其他指标进行监控来及时应对一些突发情况。避免一些故障的发生。对于 Spring Boot 应用来说我们可以...

码农小胖哥
今天
9
0
ZetCode 教程翻译计划正式启动 | ApacheCN

原文:ZetCode 协议:CC BY-NC-SA 4.0 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远。 ApacheCN 学习资源 贡献指南 本项目需要校对,欢迎大家提交 Pull Request。 ...

ApacheCN_飞龙
今天
5
0
CSS定位

CSS定位 relative相对定位 absolute绝对定位 fixed和sticky及zIndex relative相对定位 position特性:css position属性用于指定一个元素在文档中的定位方式。top、right、bottom、left属性则...

studywin
今天
9
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部