## SSH
* SSH是非对称加密,也就是公钥加密。
* 对称加密(也称为秘钥加密)
* 非对称加密(也称公钥加密)
## SSH原理图
![](https://img.kancloud.cn/73/da/73da600abdfacfb8d757dc3692988ffb_569x542.png)
1. 远程Server收到Client端用户TopGun的登录请求,Server把自己的公钥发给用户。
2. Client使用这个公钥,将密码进行加密。
3. Client将加密的密码发送给Server端。
4. 远程Server用自己的私钥,解密登录密码,然后验证其合法性。
5. 若验证结果,给Client相应的响应。
> 私钥是Server端独有,这就保证了Client的登录信息即使在网络传输过程中被窃据,也没有私钥进行解密,保证了数据的安全性,这充分利用了非对称加密的特性。
## 连接server的两种情况。
### 1. 基于口令的认证
从上面的描述可以看出,问题就在于**如何对Server的公钥进行认证?**在https中可以通过CA来进行公证,可是SSH的**publish key**和**private key**都是自己生成的,没法公证。只能通过Client端自己对公钥进行确认。通常在第一次登录的时候,系统会出现下面提示信息:
~~~
The authenticity of host 'ssh-server.example.com (12.18.429.21)' can't be established.
RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.
Are you sure you want to continue connecting (yes/no)?
~~~
上面的信息说的是:无法确认主机ssh-server.example.com(12.18.429.21)的真实性,不过知道它的公钥指纹,是否继续连接?
> 之所以用fingerprint代替key,主要是key过于长(RSA算法生成的公钥有1024位),很难直接比较。所以,对公钥进行hash生成一个128位的指纹,这样就方便比较了。
如果输入**yes**后,会出现下面信息:
~~~
Warning: Permanently added 'ssh-server.example.com,12.18.429.21' (RSA) to the list of known hosts.
Password: (enter password)
~~~
该host已被确认,并被追加到文件**known\_hosts**中,然后就需要输入密码。
### 2.免密登陆的实现原理(基于公钥认证)
![](https://img.kancloud.cn/f2/58/f2584ed62508e14f7b1a2ef1f625dce0_1456x1014.png)
1. Client将自己的公钥存放在Server上,追加在文件authorized\_keys中。
2. Server端接收到Client的连接请求后,会在authorized\_keys中匹配到Client的公钥pubKey,并生成随机数R,用Client的公钥对该随机数进行加密得到pubKey(R)
,然后将加密后信息发送给Client。
3. Client端通过私钥进行解密得到随机数R,然后对随机数R和本次会话的SessionKey利用MD5生成摘要Digest1,发送给Server端。
4. Server端会也会对R和SessionKey利用同样摘要算法生成Digest2。
5. Server端会最后比较Digest1和Digest2是否相同,完成认证过程。
## SSH实践
### 1.生成密钥操作
经过上面的原理分析,下面三行命令的含义应该很容易理解了:
~~~
$ ssh-keygen -t rsa -P '' -f ~/.ssh/id_rsa
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
$ chmod 0600 ~/.ssh/authorized_keys
~~~
ssh-keygen是用于生产密钥的工具。
* \-t:指定生成密钥类型(rsa、dsa、ecdsa等)
* \-P:指定passphrase,用于确保私钥的安全
* \-f:指定存放密钥的文件(公钥文件默认和私钥同目录下,不同的是,存放公钥的文件名需要加上后缀.pub)
首先看下面~/.ssh中的四个文件:
![](https://img.kancloud.cn/49/ec/49ecec11db593b590f00034f4e915011_592x103.png)
1. id\_rsa:保存私钥
2. id\_rsa.pub:保存公钥
3. authorized\_keys:保存已授权的客户端公钥
4. known\_hosts:保存已认证的远程主机ID(关于known\_hosts详情,见文末更新内容)
四个角色的关系如下图所示:
![](https://img.kancloud.cn/40/8b/408b76a012eab9880439f5c6a2ff6a5a_673x472.png)
> 需要注意的是:一台主机可能既是Client,也是Server。所以会同时拥有authorized\_keys和known\_hosts。
### 登录操作
~~~
# 以用户名user,登录远程主机host
$ ssh user@host
# 本地用户和远程用户相同,则用户名可省去
$ ssh host
# SSH默认端口22,可以用参数p修改端口
$ ssh -p 2017 user@host
~~~