SSH的通讯和认证
SSH的通讯和认证
转自:http://blog.sina.com.cn/s/blog_4e9440910100zxk0.html
之前一直对SSH的认证模棱两可,今天对SSH的通讯,认证和配置有了进一步的学习。
大多数文档都没有将SSH的连线加密通讯和SSH的登录加密认证特别地区分来讲,对于我这种对密钥不太熟悉的人来说常常引起一些歧义。
首先,必须把通讯和认证区分开来。通讯加密是为了确保通讯连接建立之后client和server之间相互发送的信息都是经过特定加密的,其它人得到消息也无法获取消息内容,它贯穿于整个通讯过程,在会话密钥生成前使用的是非对称密钥,在会话密钥建立之后的通讯都使用的是会话密钥(使用会话密钥速度更快,生成后取代非对称密钥进行加解密)。认证加密是为了替代传统的手工输入密码认证的一种备选认证方式,它和密码登陆有着相同的目标:服务器认同客户端的身份并允许客户端用户登陆,它的作用也是暂时性的,在用户认证成功之后就不再需要了。
对于通讯信息的加密,首先是建立会话密钥(对称密钥)的过程,鸟哥:“目前常見的網路封包加密技術通常是藉由所謂的『非對稱金鑰系統』來處理的。 主要是透過兩把不一樣的公鑰與私鑰 (Public and Private Key) 組合成為一把獨一無二的金鑰(key pair) 後, 利用這把金鑰來進行資料的加解密工作。”如下图所示,伺服器和用户端都对发送的消息用公钥加密,对接收到的消息用私钥解密。要让解密成功,就必须保证私钥与公钥是匹配的!这里的匹配是指,只需要下图中上方的公钥和私钥是匹配的,下方的公钥和私钥也是匹配的,即一对密钥负责一个方向的消息加密和解密。当然有可能的话也可以只使用一对密钥(即图中两个公钥是相同的,两个私钥也是相同的),即一对密钥负责双向的加密和解密。(两种配对方式如何选取?我认为用一对密钥比较简单吧,本文介绍的SSH会话用的是对称密钥,不涉及到这个问题。)
由于公钥和私钥的算法之间存在特殊的数学关系,从而使得这种配对成为可能。密钥对在数学上彼此相关,例如,配合使用密钥对可以实现两次使用对称密钥的效果。密钥必须配合使用:不能使用每个单独的密钥来撤消它自己的操作。这意味着每个单独密钥的操作都是单向操作:不能使用一个密钥来撤消它的操作。此外,设计两 个密钥使用的算法时,特意设计无法使用一个密钥确定密钥对中的另一个密钥。因此,不能根据公钥确定出私钥。但是,使得密钥对成为可能的数学原理也使得密钥对具有对称密钥所不具有的一个缺点。这就是,所使用的算法必须足够强大,才能使人们无法通过强行尝试,使用已知的公钥来解密通过它加密的信息。公钥利用数学复杂性以及它的单向特性来弥补它是众所周知的这样一个事实,以防止人们成功地破解使用它编码的信息。【摘自http://technet.microsoft.com/zh-cn/library/aa998077(EXCHG.65).aspx】
图 1来源于鸟哥的私房菜-SSH
在整个通讯过程中,为实现 SSH的安全连接,服务器端与客户端要经历如下五个阶段:
n 版本号协商阶段,SSH目前包括 SSH1和SSH2两个版本, 双方通过版本协商确定使用的版本
n 密钥和算法协商阶段,SSH支持多种加密算法, 双方根据本端和对端支持的算法,协商出最终使用的算法
n 认证阶段,SSH客户端向服务器端发起认证请求, 服务器端对客户端进行认证
n 会话请求阶段, 认证通过后,客户端向服务器端发送会话请求
n 交互会话阶段 ,会话请求通过后,服务器端和客户端进行信息的交互
1. 版本号协商阶段
整个阶段都是明文传输的:
1. 服务器打开端口 22,等待客户端连接。
2. 客户端向服务器端发起 TCP初始连接请求,TCP连接建立后,服务器向客户端发送第一个报文,包括版本标志字符串,格式为“SSH-<主协议版本号>.<次协议版本号>-<软件版本号>”,协议版本号由主版本号和次版本号组成,软件版本号主要是为调试使用。
3. 客户端收到报文后,解析该数据包,如果服务器端的协议版本号比自己的低,且客户端能支持服务器端的低版本,就使用服务器端的低版本协议号,否则使用自己的协议版本号。
4. 客户端回应服务器一个报文,包含了客户端决定使用的协议版本号。服务器比较客户端发来的版本号,决定是否能同客户端一起工作。
5. 如果协商成功,则进入密钥和算法协商阶段,否则服务器端断开 TCP连接。
2. 密钥和算法协商生成会话密钥
下面来讲一下SSH的通讯加密建立的过程(参考http://fly-net-cn.iteye.com/blog/119248):
1. 服务器端sshd在启动时生成自己密钥对(pub-s/ppk-s…),如果之前有档案的话可以直接使用。
2. 客户端请求连接。【明文】
3. 服务器端发送自己的主机公钥,服务公钥和8个字节的cookie给客户端。【明文】
4. 客户端立即把从服务器端收到cookie、主机密钥、和服务 密钥作为参数计算出会话号(计算方法和服务器端生成会话号的方法相同,所以两者的会话号也是相同的,这为会话密钥相同提供了前提条件),并用会话号的前16字节和随机数的前16字节异或后生成一个值x,用服务器端公钥pub-s加密x,发送给服务器。【pub-s加密】
5. 客户端记录服务器端的公钥(人为检查服务器公钥的指纹码的正确性,可以看作client端的自我保护),追加在~/.ssh/known_hosts文件中。
6. 服务器用自己的主机私钥和服务私钥解密出x,同样异或会话号的前16字节之后就获得客户端的产生的随机数的前16字节,它就是会话密钥!
7. 加密连接建立。使用统一的会话密钥进行双向的加密和解密。服务器首先给用户端发送加密的包,通知服务器收到了客服端前面发送的包。下面就是客户端的认证过程了。
总结起来就是要交换确定会话号和会话密钥(交换信息,生成会话号和会话密钥的详细算法常见http://fly-net-cn.iteye.com/blog/119248)。在实际传送信息时采用对称密钥加密算法,而不采用公开密钥加密算法(RSA/DSA等),因为公开密钥算法(加密&解密)速度较慢。在大多数对称算法中,加密密钥和解密密钥是相同的,都是进行xor计算。会话密钥只使用于通信期间,下次通信再重新启用一个新的会话密钥。
通过以上步骤,服务器端和客户端就取得了相同的会话密钥和会话ID。
u 对于后续传输的数据,两端都会使用会话密钥进行加密和解密,保证了数据传送的安全
u 在认证阶段,两端会使用会话 ID用于认证过程。
3. 认证阶段
连接建立之后,客户端的认证步骤:
1. 客户端向服务器发送认证请求,包含自己的用户名等。
2. 服务器检查本地档案,用户不存在,返回错误信息SSH_SMSG_FAILURE包;用户存在且不需要认证,返回认证成功SSH_SMSG_SUCCESS 包;用户存在且需要认证,则通知用户端进行认证,返回支持的认证方式。前两种情况下直接跳到第5步。
3. 客户端接收到认证消息后,不停地向服务器发包申请用各种不同的方法进行认证(认证交互过程后文有介绍),直到时限已到服务器关闭连接为止。
4. 服务器根据认证消息返回认证结果,对任何一个申请,如果服务器接受,就以 SSH_SMSG_SUCCESS 包回应。如果不接受,或者是无法识别,则以 SSH_SMSG_FAILURE 包回应。
5. 如果认证通过,客户端向服务端提交会话请求,服务器则进行等待,处理客户端的请求。会话请求分为这样几类:申请对数据传送进行压缩、申请伪终端、启动 X11、TCP/IP 端口转发、启动认证代理、运行 shell、执行命令。
具体的认证方式有三种:
1. 密码认证
只要你知道自己帐号和口令,就可以登录到远程主机。所有传输的数据都会被加密,但是不能保证你正在连接的服务器就是你想连接的服务器。可能会有别的服务器在冒充真正的服务器,也就是受到“中间人”这种方式的攻击。
2. RSA认证与DSA认证
a) 客户端先为自己创建一对密匙,并把公匙放在需要访问的服务器上;
b) 客户端会向服务器发出请求,请求用你的密匙进行安全验证;
c) 服务器收到请求之后,在该服务器目录下寻找公匙,然后把它和你发送过来的公匙进行比较。若两密匙一致,服务器就用公匙加密“质询”(challenge)(一个随机数)并把它发送给客户端;
d) 客户端收到“质询”之后就可以用私钥解密后,再把这个随机数发送给服务器。
e) 服务器检查接收到的数和之前自己生成的随机数是不是相同的,如果相同,服务器就认为客户端确实有匹配的专用密钥,它能成功的对服务器的消息进行解密!
4. 会话请求阶段
1. 服务器等待客户端的请求;
2. 认证通过后,客户端向服务器发送会话请求;
3. 服务器处理客户端的请求。请求被成功处理后, 服务器会向客户端回应 SSH_SMSG_SUCCESS包,SSH进入交互会话阶段;否则回应 SSH_SMSG_FAILURE包,表示服务器处理请求失败或者不能识别请求。
5. 交互会话阶段
在这个模式下,数据被双向传送(由会话密钥加解密):
1. 客户端将要执行的命令加密后传给服务器;
2. 服务器接收到报文,解密后执行该命令,将执行的结果加密发还给客户端;
3. 客户端将接收到的结果解密后显示到终端上.
参考文献:
http://www.ibm.com/developerworks/cn/linux/security/openssh/part1/index.html (推荐)
http://fly-net-cn.iteye.com/blog/119245 (推荐)
http://blog.csdn.net/oncoding/article/details/4365062 (推荐)
http://technet.microsoft.com/zh-cn/library/aa998077(EXCHG.65).aspx
http://blog.csdn.net/oncoding/article/details/4365062
http://club.aofix.com/forum.php?mod=viewthread&tid=12257
http://linux.vbird.org/linux_server/0310telnetssh.php#ssh_secure
http://jiajun.iteye.com/blog/621309
SSH的一些技巧
1. sftp & scp
SSH除了提供远程登录终端的功能外,还提供sftp-server。当你想要从远端伺服器下载或上传档案就必須要使用 sftp 或 scp。
2. 免询问登陆
如果客户端没有保存服务器的公钥,客户端程序会询问用户是否添加当前服务器的公钥到known_hosts文件中。在大量登陆和使用脚本登陆的情况下,想采用免询问的登陆方式可以采用以下方法:
ssh -o StrictHostKeyChecking=no root@hostip
3. 免密码登陆(RSA认证方式)
先理解前面“认证阶段”的认证方式,主要思想就是在客户端生成自己的密钥对,将公钥添加到服务器端的~/.ssh/ authorized_keys文件末尾。
ssh-keygen [-t rsa|dsa]
可选加密方式有rsa和dsa,默认为rsa。如果设置密码那么在认证时客户端这边需要输入该密码,用于开启私钥解密。
默认生成的目录在~/.ssh/下的id_rsa(私钥)和id_rsa.pub(公钥),可以更改。
拷贝到目标服务器上:
scp ~/.ssh/id_rsa.pub user@hostip:~
追加公钥到authorized_keys文件中:
cd !/.ssh && cat id_rsa.pub >> .ssh/authorized_keys
4. SSH反应缓慢的问题
设置sshd_config中UseDNS为no。详细可参见博客。
http://blog.sina.com.cn/s/blog_4e9440910100zn28.html
SSH的通讯和认证的更多相关文章
- Linux中SSH服务基于key认证实践
众所周知ssh是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议,它默认工作在tcp的22号端口,具体实现的软件有:openssh(centos默认安装的),dropbear.ssh协议目前 ...
- 批量SSH key-gen无密码登陆认证脚本
SSH key-gen无密码登录认证脚本 使用为了让linux之间使用ssh不需要密码,可以采用了数字签名RSA或者DSA来完成.主要使用ssh-key-gen实现. 通过 ssh-key-gen 来 ...
- Shell批量SSH免交互登录认证
脚本实现功能:批量或单个SSH免交互登录认证 脚本应用场景:当部署集群时,大多数实现要配置好管理节点与从节点的SSH免交互登录,针对这样的情况,写了下面脚本,简化工作. 脚本支持系统:Ubuntu和C ...
- Linux的SSH免密登录认证过程研究
一.先看下SSH免密登录使用到的工具和生成的文件 工具:ssh-keygen用于生成秘钥文件,其中秘钥分为公钥和私钥.ssh-copy-id用于复制公钥文件到被控制机. 文件:ssh-keygen生成 ...
- Linux 利用Google Authenticator实现ssh登录双因素认证
1.介绍 双因素认证:双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统.双因素认证是一种采用时间同步技术的系统,采用了基于时间.事件和密钥三变量而产生的一 ...
- ssh 服务器之间公钥认证方式的配置
前言 项目中需要编写脚本在服务器之间上传或者下载文件,但没有相关服务器来测试脚本,于是就着手安装两台server,然后用ssh的相关命令去配置server之间公钥认证登录. 步骤 1. 在VM Box ...
- Linux ssh双向免密认证
一.实现原理 使用一种被称为"公私钥"认证的方式来进行ssh登录."公私钥"认证方式简单的解释是: 首先在客户端上创建一对公私钥(公钥文件:~/.ssh/id_ ...
- ssh客户端连接报认证失败
最近有个应用在并发导出的时候,报错了ssh认证失败,原来串行的时候都正常,经查,可能是ssh连接数不够的原因,这个问题刚好之前有个java开发反馈过,linux默认的ssh连接数为10个. 解决如下: ...
- ssh的秘钥认证
ssh秘钥认证简述 通常我们会使用x-shell.putty.MobaXterm等支持ssh连接的工具去登录服务器进行管理,而执行ssh命令.scp命令等从一台服务器登录另外一台服务器的时候,通常需要 ...
随机推荐
- 安卓程序代写 网上程序代写[原]vim编辑器配置及常用命令
最近工作不安分, 没有了刚入行时候的锐气, 不知道什么时候开始懈怠起来, 周末在电脑旁边看新闻, 搞笑图片, 追美剧, 一坐就是一天, 很是空虚. 我需要摆脱这种状态, 正好想学习一下安卓底层, An ...
- PHP最全笔记(四)(值得收藏,不时翻看一下)
// 序列化(串行化) # 数据传输均是字符串类型 # 除了资源类型,均可序列化 # 序列化在存放数据时,存放数据本身,也存放数据类型 1.在网络传输数据时:2.为了将数组或对象放在磁盘时 # 序列化 ...
- cookie是如何保存到客户端,又是如何发送到服务端
Cookie相关的Http头 有 两个Http头部和Cookie有关:Set-Cookie和Cookie. Set-Cookie由服务器发送,它包含在响应请求的头部中.它用于在客户端创 ...
- [Node.js] 05 - Modules and Function
一个 Node.js 文件就是一个模块,这个文件可能是JavaScript 代码.JSON 或者编译过的C/C++ 扩展. 模块是Node.js 应用程序的基本组成部分,文件和模块是一一对应的. No ...
- Hibernate -- Dao层 -- CURD -- 随记
根据Where 参数 查询记录总数 .拼接SQL语句 .获取Session(hibernateTemplate.getSessionFactory().getCurrentSession()),调用C ...
- java.security.ProviderException: java.security.KeyException
本机部署没问题,部署到linux服务器报错: javax.net.ssl.SSLException: java.security.ProviderException: java.security.Ke ...
- 【JS加密库】SJCL :斯坦福大学JS加密库
斯坦福大学Javascript加密库简称SJCL,是一个由斯坦福大学计算机安全实验室创立的项目,旨在创建一个安全.快速.短小精悍.易使用.跨浏览器的JavaScript加密库. 斯坦福大学下载地址:h ...
- 使用 JdbcTemplate 查询数据时报错:列名无效(已解决)
又犯了一个错误. 争取没有下次了. 就算再犯,也要知道去哪找答案. 所以,记录一下,以示警戒. 报错 使用 JdbcTemplate 查询数据时,出现异常: PreparedStatementCall ...
- ORA-01841: (full) year must be between -4713 and +9999,
OGG报错日志: 2018-09-21 08:52:39 WARNING OGG-01003 Oracle GoldenGate Delivery for Oracle, rep_1b.prm: Re ...
- L - Fire Game
Fat brother and Maze are playing a kind of special (hentai) game on an N*M board (N rows, M columns) ...