SSH协议总结
一.SSH协议介绍
SSH:安全外壳协议。SSH 为 Secure Shell 的缩写,它是建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议可以有效防止远程管理过程中的信息泄露问题。
二.SSH协议结构
SSH是由客户端和服务端的软件组成的,有两个不兼容的版本分别是:1.x和2.x。 用SSH 2.x的客户程序是不能连接到SSH 1.x的服务程序上去的。OpenSSH 2.x同时支持SSH 1.x和2.x。
服务端是一个守护进程(daemon),他在后台运行并响应来自客户端的连接请求。服务端一般是sshd进程,提供了对远程连接的处理,一般包括公共**认证、**交换、对称**加密和非安全连接。
客户端包含ssh程序以及像scp(远程拷贝)、slogin(远程登陆)、sftp(安全文件传输)等其他的应用程序。
三.SSH原理及工作过程
原理:SSH协议是基于非对称加密方法的,服务器和客户端都会生成自己的公钥和私钥。
工作过程:
SSH建立连接主要分为以下几个过程:
1.TCP三次握手
2.版本协商
(1)客户端通过TCP三次握手与服务器的SSH端口建立TCP连接。
(2)服务器通过建立好的连接向客户端发送一个包含SSH版本信息的报文,格式为“SSH-<SSH协议大版本号>.<SSH协议小版本号>-<软件版本号>”,软件版本号主要用于调试。
(3)客户端收到版本号信息后,如果服务器使用的协议版本号低于自己的,但是客户端能够兼容这个低版本的SSH协议,则就使用这个版本进行通信。否则,客户端会使用自己的版本号。
(4)客户端将自己决定使用的版本号发给服务器,服务器判断客户端使用的版本号自己是否支持,从而决定是否能够继续完成SSH连接。
(5)如果协商成功,则进入**和算法协商阶段。
3.算法协商
从客户端和服务器相互发出 Key Exchange Init 请求开始,报文中包含自己支持的公钥算法列表,加密算法列表,MAC(Message Authentication Code,消息验证码)算法列表,压缩算法列表等
kex_algorithms:
**交换算法,里边即包含我们使用的D-H算法,用于生成会话**服务器主机**算法,可以采用 ssh-rsa,ssh-dss,ecdsa-sha2-nistp256
server_host_key_algorithms:
服务器主机**算法,可以采用 ssh-rsa,ssh-dss,ecdsa-sha2-nistp256 ,有公钥和私钥的说法,
encryption_algorithms_client_to_server:对称加密算法,常用的有 aes128-cbc,3des-cbc
mac_algorithms_client_to_server:MAC算法,主要用于保证数据完整性
compression_algorithms_client_to_server: 压缩算法
Language:语言标志的名称列表。如果没有语言优先级,该名称列表应为空。
First KEX Packet Follows:
表明是否有一个猜测的**交换数据包跟随。如果将会发送一个猜测的数据包,该域必须是TRUE。如果不会发送猜测的数据包,该域必须是FALSE。
4.**协商
服务器端和客户端利用Diffie-Hellman**交换算法,主机**对等参数,生成共享**和会话ID。会话**用于在后续的通信过程中两端对传输的数据进行加密和解密,而会话ID用于认证过程。
(1)客户端接要发送 DH 算法**对的公钥;
(2)服务器发送 DH 算法**对的公钥,双方协商出只有他们才知道的会话**;
(3)客户端发送一个 New Keys 数据包,表示双方构建了一个加密通道。
5.认证阶段
(1)客户端向服务器端发送认证请求,请求中包含用户名,认证方法,密码或**。
(2)服务器端对客户端进行认证,如果认证失败,则向客户端发送失败消息,其中包含可以再次认证的方法列表。
(3)客户端再次使用支持的认证方法中的一种进行认证,直到达到认证次数上限被服务器终止连接,或者认证成功为止。
SSH支持的两种认证方式:
密码认证:客户端通过用户名/密码进行认证,将使用会话**加密后的用户名和密码发送给服务器,服务器解密后与系统保存的用户名和密码进行对比,并向客户端返回认证成功或失败的消息。
**认证:采用数字签名来进行认证,目前可以通过RSA和DSA两种算法实现数字签名,客户端通过用户名,公钥以及公钥算法等信息来与服务器完成验证。首先在客户端生成一对**(ssh-******);并将客户端的公钥ssh-copy-id 拷贝到服务端;当客户端再次发送一个连接请求,包括ip、用户名;服务端得到客户端的请求后,会到authorized_keys中查找,如果有响应的IP和用户,就会随机生成一个字符串;服务端将使用客户端拷贝过来的公钥进行加密,然后发送给客户端;得到服务端发来的消息后,客户端会使用私钥进行解密,然后将解密后的字符串发送给服务端;服务端接受到客户端发来的字符串后,跟之前的字符串进行对比,如果一致,就允许免密码登录。
6.会话请求
(1)服务器等待客户端请求。
(2)认证完成后,客户端想服务器发送会话请求。
(3)服务器处理客户端请求,完成后,会向客户端回复SSH_SMSG_SUCCESS报文,双方进入交互会话阶段。如果请求未被成功处理,则服务器返回SSH_SMSG_FAILURE报文,表示请求处理失败或者不能识别客户端请求。
7.交互会话
(1)客户端将要执行的命令加密发送给服务器。
(2)服务器收到后,解密命令,执行后将结果加密返回客户端。
(3)客户端将返回结果解密后显示到终端上。
四.DH算法原理
服务器首先生成两个数G、P,P为一个非常大的素数,作为DH算法的模;G作为密码发生器,服务器将这两个数发给客户端,用于**的交换。
客户端生成一个数(客户端的私钥)x(0<x<P,但x应该大一点,否则的那个G特别小的时候生成的**长度可能会很短,服务器会拒绝),计算e=(G^x)%P,得到的e就是客户端的公钥,客户端将e发送给客户端。
服务端也同客户端一样,生成一个数Y,计算f=(G^Y)%P,将服务器公钥f发送给客户端。
现在服务器与客户端都知道了对方的公钥,双方把对方的公钥作为自己模幂运算的底数进行运算,服务器计算K1=(e^Y)%P,客户端计算K2 = (f^x)%P,可以证明K1 == K2,得到的K值便是双方所交换的秘钥。
五.LIBSSH2的API学习。
windows连接服务器发送shell命令几个步骤:
WSAStartup(),打开socket链接库
socket(),初始化一个socket套接字
connect(),连接到ssh服务器
libssh2_session_init(),初始化一个ssh连接
libssh2_session_handshake(),将socket和session握手通信
libssh2_userauth_password(),验证登陆
libssh2_channel_open_session(),打开通道
libssh2_channel_exec(),发送shell命令
libssh2_channel_read(),读取命令处理结果
- 算法协商原理
现在双方知道对方支持的算法,但是应该怎样决定每个类型实际所使用的算法呢?
每个算法类型列表的第一个算法必须是首选的算法,服务器应以客户端的算法优先级作为考虑,就拿交换算法举例:
现在服务器有三个算法dh1,dh2,dh3
客户端有两个算法dh3,dh2
那么服务器的首选算法是dh1,而客户端是dh3,客户端此时知道服务器有dh3算法,因此客户端就确认使用dh3算法。服务器发现自己的首选算法与客户端不同,而自己拥有客户端的首选算法,因此服务器也确认使用dh3算法。
再看另一个情况
服务器:dh1,dh2,dh3
客户端:dh4,dh3,dh1
这时服务器没有客户端的首选算法,客户端会使用第二个算法dh3,此时服务器也支持第二个算法,双方将确定使用dh3算法。
如果服务器和客户端双方没有共同的算法,这次会话将会终止。