蓝月
谦虚使人进步, 骄傲使人落后
博客园 首页 新随笔 联系 订阅 管理 随笔 - 1 文章 - 0 评论 - 0
一, 对称加密与非对称加密
对称加密: 加密和解密的秘钥使用的是同一个.
非对称加密: 非对称加密算法需要两个密钥: 公开密钥 (publickey) 和私有密钥; 简称公钥和私钥
对称加密
对称加密的密码强度高, 较难破解. 但是秘钥的保存成为了一个重要的问题, 特别是如果机群庞大的时候, 一旦某个客户端暴露了秘钥, 会给整个系统带来严重的安全问题
非对称加密
公钥加密后的密文, 只能通过对应的私钥进行解密. 而通过公钥推理出私钥的可能性微乎其微. 私钥是 Server 端独有, 而且私钥并不会在网络中进行传输, 这一定程度上保证了数据的安全性, 充分利用了非对称加密的特性
非对称加密的过程:
1 客户端向服务器发送请求, 并得到服务器传来的公钥
2-4 客户端利用从服务器得到公钥对登录数据 (用户名和密码或其他验证数据) 进行加密; 然后将加密后的数据传给服务器
5-7 服务器利用私钥将从客户端收到的数据进行解密. 并将解密后的数据与正确数据 (数据库中存储的用户名和密码或其他) 进行校验, 根据得到校验结果允许或拒绝此次登录请求; 并将最后结果通知客户端
二, 非对称加密的安全性问题
从上面的分析中, 我们得知了非对称加密确实解决了一定的安全问题, 那么它就一定安全了吗? 答案是绝对否定的. 因为通过上面的分析, 我们得知客户端对于服务器方是没有认证的. 而这时如果一个假冒的服务器方将自己的公钥发给了客户端, 它可以很简单的把客户端的加密数据进行解密, 因为公钥和私钥都是它自己的啊. 这样客户端的数据就被窃取了. 这种攻击方式叫做中间人攻击. 其原理如下:
三, SSH 原理
因为非对称加密体质非常耗费系统资源, 因此 SSH 仅将非对称加密用于登录连接过程, 而连接后的数据交互采用了对称加密. 我们通过上面得知, 即使是非对称加密也存在一个问题 -- 如何解决中间人攻击?
https 中针对中间人攻击采取了公证机制 -- 通过 CA 来进行公证, 可是 SSH 的公钥和私钥都是自己生成的, 没法公证. 只能通过 Client 端自己对公钥进行确认.
因此, SSH 引入了 known_hosts 文件. 客户端的每次连接请求, 服务器都会将相关信息与 known_hosts 文件中的信息进行匹配, 如果是第一次连接, 服务器会将相关信息存储在 known_hosts 文件中, 在这个过程中, 服务器会请求客户端的用户进行确认; 拿什么确认呢? 公钥指纹! 什么是公钥指纹?
因为公钥很长, 长达 1024 位甚至 2048 位或更长, 如果比较这么长的数据会很耗费系统资源. 所以这里的公钥指纹是指利用 MD5 算法对公钥进行加密后形成的 128 位的一个数据; 客户端利用这个从服务器获取到的公钥加密后的公钥指纹和真正服务器的公钥 (需提前获取) 加密后的公钥指纹进行比较, 如果一致的话, 用户需要输入 yes 确认此次认证, 如果不一致的话, 有可能遭到了中间人攻击, 用户需要输入 no 对此次认证进行中断, 防止数据泄露. 如图:
如果不是第一次连接, 客户端 (登录方) 会将自己的 known_hosts 文件中的公钥指纹与服务器传来的公钥指纹进行对比, 如果一致, 连接会继续, 客户端输入用户名和密码直接登录就可以. 如果不一致, 客户端会判定此次连接遭到了中间人攻击, 并阻止此次连接, 如图:
如果是用户主动重新部署了 SSH 服务器, 并且确认此次连接无误的话, 用户需要在客户端 (登录方) 的 known_hosts 文件中删除与该地址对应的公钥数据, 重新进行 SSH 连接认证即可
四, SSH 免密登录原理
基于口令的认证方式每次登录都需要输入密码, 这是比较麻烦的一件事情, 为此, SSH 引入了基于公钥认证的登录方式, 这也是 SSH 免密登录的依据, 那么基于公钥认证的登录方式具体步骤是怎样的呢?
1. 登录端 A 生成公钥和私钥, 并 (手动) 将公钥追加到被登录端 B 的 authorized_key 文件中
2. 登录端 A 向被登录端 B 发送连接请求, 并将公钥发送给被登录端 B
3. 被登录端 B 接受登录端 A 发来的公钥, 并将该公钥与自己的 authorized_key 文件中的所有存储的公钥进行比较, 如果并未发现有此公钥存在, 则登录端 A 需要进行口令认证与被登录端 B 进行连接. 如果在 authorized_key 文件中找到了与登录端 A 发送的公钥相同的公钥, 则生成随机数 R, 并利用公钥加密该随机数得到 publickey(R), 最后被登录端 B 将 publickey(R) 传给登录端 A
4. 登录端 A 利用私钥对 publickey(R) 进行解密得到 R, 登录端 A 和被登录端 B 通信时会产生一个会话 ID(sessionKey). 登录端 A 利用 MD5 算法将 R 和 ID 进行加密, 并将加密后的数据传给被登录端 B
5. 被登录端 B 也利用 MD5 算法对 R(被登录端 B 在第 3 步中随机生成的)和会话 ID(二者的会话属于同一会话, 因此会话 ID sessionKey 是相同的)进行加密. 并将加密后的数据与第四步登录端传来的加密数据进行比较, 如果相同, 则允许此次登录端 A 的连接请求, 并与之建立连接. 如果不同, 则二者继续进行基于口令认证的连接请求
注意:
免密登录的任何一个环节出现不匹配时, 登录端 A 和被登录端 B 的连接将会被转换为基于口令的认证连接
五, 用生活实例来演示免密登录
老板 Boss 在服务器 B 上创建了一个 userb 用户, 可是他回到家后想用客户机 A 使用 userb 用户连接服务器 B
首先, 老板在自己办公室的客户机 A 上创建了秘钥, 包括公钥和私钥. 老板把公钥传到公司的服务器 S 上; 可是这个老板不可能把公司的所有事情都包了, 那样太累了, 于是他在公司的服务器 S 上做了一个允许访问该服务器的 "电脑编号 - 各级部门经理账号" 认证列表, 该认证列表中包含了公司的所有部门经理的办公电脑的 Mac 地址和其对应的不同级别的用户账号. 只有被该列表包含的 "电脑编号 - 各级部门经理账号" 才有资格免密登录此服务器进行办公
有一天老板想要统计公司今年的盈亏状况, 所以要查看公司的账单, 老板在客户机 A 上使用 SBoss 登录服务器 S; 当服务器 S 收到老板的连接请求后, 服务器 B 上的 "电脑编号 - 各级部门经理账号" 会判断自己里边是否有与客户机 A 通过 SBoss 登录服务器的认证, 如果没有的话, 老板还得输入 SBoss 在服务器 B 上的密码进行登录; 如果有的话, 服务器 B 会发送一个用客户机 A 上的公钥加密的随机数给客户机 A, 客户机 A 用私钥解密这个随机数, 并用 MD5 算法对该随机数和当前会话 ID 组合的数据进行加密, 然后将加密后的数据发送给服务器 S, 服务器 S 也利用 MD5 算法对该随机数和当前会话 ID 进行加密, 并与客户机 A 传来的加密数据进行对比. 根据对比结果决定是否允许此次免密登录请求
上文中的抽象事物与 SSH 相关文件对应关系如下:
老板 ===> 操作计算机用户的相关管理人员
服务器 S ===> SSH 服务端
客户端 A ===> SSH 客户端
SBoss ===> SSH 服务端管理员账号
公钥 ===> SSH 客户端的 id_rsa.pub 文件
私钥 ===> SSH 客户端号的 id_rsa 文件
"电脑编号 - 各级部门经理账号" ===> SSH 服务端的 authorized_keys 文件
六, SSH 免密登录实战
单向免密登录方法一
1. 客户端 A 执行以下命令, 生成秘钥
SSH-keygen -t rsa
注意: 一路回车即可
2. 客户端 A 执行以下命令, 将公钥传给服务端 B
SSH-copy-id [服务器 B 的 IP 地址]
3. 客户端 A 执行以下命令(注意: 先不要执行它, 若 B 出现登录不了 A 的状况再执行)
SSH-add id_rsa
4. 服务器 A 执行以下命令验证
SSH [服务端 B IP 地址]
或
SSH [服务端 B 上的用户名]@[服务端 B IP 地址]
5. 如果出错的话, 可能是以下几种原因
1. 两台机器均设置相应的免密登录
2.
chmod 700 /home/[用户名]/.SSH/
chmod 600 /home/[用户名]/.SSH/authorized_keys
3. 修改 / etc/SSH/ssh_config 配置文件如下关键字
GSSAPIAuthentication no
单向免密登录方法二
1. 客户端 A 生成公钥和秘钥
SSH-keygen -t rsa
注意:
一路回车即可
2. 客户端 A 将公钥传给服务端 B
scp id_rsa.pub root@192.168.5.17:~/.SSH/
3. 服务端 B 将 A 的公钥追加到自己的 authorized_keys 文件中(如果没有该文件, 则先新建再追加)
- touch authorized_keys
- cat id_rsa.pub>> authorized_keys
4. 客户端 A 执行以下命令(注意: 先不要执行它, 若 B 出现登录不了 A 的状况再执行)
SSH-add id_rsa
5. 客户端 A 登录服务端 B
SSH root@192.168.5.17
双向免密登录
1.. 编辑主机 A 和主机 B 的 sshd 配置文件 VIM /etc/SSH/ssh_config
- RSAAuthentication yes
- PubkeyAuthentication yes
- AuthorizedKeysFile .SSH/authorized_keys
2. 重启 sshd 服务
service sshd restart
3. 主机 A 新建用户 usea, 主机 B 新建用户 userb
主机 A 的操作:
- useradd usera
- passwd usera
主机 B 的操作:
- useradd userb
- passwd userb
4. 主机 A 使用 usera 用户登录, 创建 SSH 秘钥
- su usera
- SSH-keygen -t rsa (一直回车)
5. 主机 B 使用 userb 用户登录, 创建 SSH 秘钥
- su userb
- SSH-keygen -t rsa (一直回车)
6. 主机 A 使用 usera 在 ~/.SSH/ 目录下新建 authorized_keys 文件, 并且将 usera 和 userb 的公钥 (id_rsa.pub) 复制到该文件中
- cd ~/.SSH/
- touch authorized_keys
将主机 A 的 usera 公钥复制进主机 A 的 usera 的目录下的 authorized_keys 文件
cat id_rsa.pub> authorized_keys
将主机 B 的 userb 公钥追加到主机 A 的 usera 的目录下的 authorized_keys 文件
SSH userb@[主机 B 的 IP 地址] cat /home/userb/.SSH/id_rsa.pub>> authorized_keys
7. 主机 A 使用 usera 用户执行以下命令
- chmod 700 /home/usera/.SSH/
- chmod 600 /home/usera/.SSH/authorized_keys
8. 将主机 A 的用户 usera 的~/.SSH 目录下的两个配置文件 authorized_keys,known_hosts 复制到主机 B 的 userb 用户的~/.SSH 目录下
scp authorized_keys known_hosts userb@[主机 B 的 IP 地址]:~/.SSH/
9. 主机 B 使用 userb 用户设置指定文件权限
- chmod 700 /home/userb/.SSH/
- chmod 600 /home/userb/.SSH/authorized_keys
10. 到此, 主机 A 和 B 就可以通过 usera 和 userb 通过 SSH 免密登录了
SSH userb@[主机 B 的 IP 地址]
SSH usera@[主机 A 的 IP 地址]
来源: https://www.cnblogs.com/viplanyue/p/12700775.html