最近在做ssh2联动交换机模块,看到libssh2-1.9.0版本对于用户认证有三种不同的方式:
① password(默认)② keyboard-interactive ③ publickey
看代码并不是太理解,所以查询了一番,SSH2通信大致分为两步,以下是对通信过程的简单理解:
生成共享秘钥(加密通道):
1. 客户端先向服务器发起TCP连接。
2. 服务器回复自己所支持的SSH版本,若客户端也支持,则继续。
3. 双方协商一个公共的加密算法,最终使用的加密法一般由机器上加密法列表的排序决定:客户端加密法列表上出现的第一个服务器端也支持的加密算法,将用于双方加密传输的实现。
4. 采用Diffie-Hellman算法,生成共享秘钥(这一块是重点)
① 客户端发起请求,服务器取两个数P、G ,其中P是一个很大的素数,G是P的一个模p本原单位根(primitive root module p),然后将G和P发送给客户端。
② 客户端C会生成一个不公开的随机数a,计算CKey = G ^a mod P,将CKey发送给服务器。
③ 服务器S会生成一个不公开的随机数b,计算SKey = G ^b mod P,将SKey发送给客户端,同时发送的还有服务器的公钥。
④ 客户端C收到SKey后,计算共享秘钥:K = SKey ^a mod P = G ^(b * a) mod P,同时验证此公钥是否存在自己的known_hosts文件中,若不存在或不一致,则会提示是否确认连接。
⑤ 服务器S收到CKey后,计算共享秘钥:K = CKey ^b mod P = G ^(a * b) mod P。
用户认证:
第一种方式:password
根据前一步生成的共享秘钥,直接输入用户密码进行验证。(一般情况下,若没有特殊指定其他认证方式,默认用此认式)
第二种方式:keyboard-interactive
这个方式是必须启用键盘输入才可以,防止记住密码后直接登录。
第三种方式:publickey
1. 客户端生成一对秘钥:public/private key,并将公钥放到服务器的 authorized_keys 文件中。
2. 客户端发送一个秘钥ID给服务器。
3. 服务器收到之后,会在authorized_keys 文件中查找是否有此ID的公钥, 如果有,则服务器生成一个随机数x,并用客户端的公钥加密后通过加密通道发送给客户端。
4. 客户端收到之后,用私钥解除x,然后在本地为随机数x做MD5哈希,并通过加密通道发送给服务器。
5. 服务器为随机数x做MD5哈希,然后用共享秘钥加密后与客户端发送过来的数做比较,若一致,则认证通过。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
结语:
以上就是我对于SSH2通信的一个大致理解,若有错处,望指出,大家共同进步,谢谢!