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的通讯和认证的更多相关文章

  1. Linux中SSH服务基于key认证实践

    众所周知ssh是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议,它默认工作在tcp的22号端口,具体实现的软件有:openssh(centos默认安装的),dropbear.ssh协议目前 ...

  2. 批量SSH key-gen无密码登陆认证脚本

    SSH key-gen无密码登录认证脚本 使用为了让linux之间使用ssh不需要密码,可以采用了数字签名RSA或者DSA来完成.主要使用ssh-key-gen实现. 通过 ssh-key-gen 来 ...

  3. Shell批量SSH免交互登录认证

    脚本实现功能:批量或单个SSH免交互登录认证 脚本应用场景:当部署集群时,大多数实现要配置好管理节点与从节点的SSH免交互登录,针对这样的情况,写了下面脚本,简化工作. 脚本支持系统:Ubuntu和C ...

  4. Linux的SSH免密登录认证过程研究

    一.先看下SSH免密登录使用到的工具和生成的文件 工具:ssh-keygen用于生成秘钥文件,其中秘钥分为公钥和私钥.ssh-copy-id用于复制公钥文件到被控制机. 文件:ssh-keygen生成 ...

  5. Linux 利用Google Authenticator实现ssh登录双因素认证

    1.介绍 双因素认证:双因素身份认证就是通过你所知道再加上你所能拥有的这二个要素组合到一起才能发挥作用的身份认证系统.双因素认证是一种采用时间同步技术的系统,采用了基于时间.事件和密钥三变量而产生的一 ...

  6. ssh 服务器之间公钥认证方式的配置

    前言 项目中需要编写脚本在服务器之间上传或者下载文件,但没有相关服务器来测试脚本,于是就着手安装两台server,然后用ssh的相关命令去配置server之间公钥认证登录. 步骤 1. 在VM Box ...

  7. Linux ssh双向免密认证

    一.实现原理 使用一种被称为"公私钥"认证的方式来进行ssh登录."公私钥"认证方式简单的解释是: 首先在客户端上创建一对公私钥(公钥文件:~/.ssh/id_ ...

  8. ssh客户端连接报认证失败

    最近有个应用在并发导出的时候,报错了ssh认证失败,原来串行的时候都正常,经查,可能是ssh连接数不够的原因,这个问题刚好之前有个java开发反馈过,linux默认的ssh连接数为10个. 解决如下: ...

  9. ssh的秘钥认证

    ssh秘钥认证简述 通常我们会使用x-shell.putty.MobaXterm等支持ssh连接的工具去登录服务器进行管理,而执行ssh命令.scp命令等从一台服务器登录另外一台服务器的时候,通常需要 ...

随机推荐

  1. win7(64bit)+python3.5+pyinstaller3.2安装和测试

    最近因为做项目需要,需要在win7中安装pyinstaller用于将.py文件生成脱离python平台的可执行程序*.exe文件. 安装步骤 第一步:安装python3.5 [下载python3.5的 ...

  2. chrome调试手机webview中页面

    http://blog.csdn.net/freshlover/article/details/42528643 注: 1. 可以调试真机上页面(USB连接)和虚拟机上页面 2. 手机系统需要4.4+ ...

  3. Java知多少(36)内部类及其实例化

    在 Java 中,允许在一个类(或方法.语句块)的内部定义另一个类,称为内部类(Inner Class),有时也称为嵌套类(Nested Class). 内部类和外层封装它的类之间存在逻辑上的所属关系 ...

  4. Tomcat容器做到自我保护,设置最大连接数(服务限流:tomcat请求数限制)

    http://itindex.net/detail/58707-%E5%81%87%E6%AD%BB-tomcat-%E5%AE%B9%E5%99%A8 为了确保服务不会被过多的http长连接压垮,我 ...

  5. 使用UWA GOT优化Unity性能和内存

    优化百科: https://blog.uwa4d.com/archives/Index.html https://blog.uwa4d.com/archives/Introduction_UWAGOT ...

  6. 设计模式-行为型模式,python备忘录模式

    备忘录模式 备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象.备忘录模式属于行为型模式. 介绍 意图:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该 ...

  7. [Tensorflow] Cookbook - Retraining Existing CNNs models - Inception Model

    From: https://github.com/jcjohnson/cnn-benchmarks#alexnet 先大概了解模型,再看如果加载pre-training weight. 关于retai ...

  8. 通信原理之TCP/IP基本概念 (二)

    本来想写写,但发现有人写的很好了,不造轮子了!  直接转了 一.为什么会有TCP/IP协议 在世界上各地,各种各样的电脑运行着各自不同的操作系统为大家服务,这些电脑在表达同一种信息的时候所使用的方法是 ...

  9. Excel 保护工作表

    1.选取整张表格,格式--设置单元格格式--锁定状态 2.将用户可编辑区域解锁 3.在审阅--保护工资表,设置除第一行不选,其他全选,添加密码保护,确定

  10. 百度网盘上下载文件,调用api接口的请求方式和参数

    REST api 功能:下载单个文件. Download接口支持HTTP协议标准range定义,通过指定range的取值可以实现断点下载功能. 例如: 如果在request消息中指定“Range: b ...